2017-05-05 2 views
0

Je reçois la vente totale en utilisant la requête suivante.La fonction Agréger renvoie une valeur incorrecte lors de la jonction d'un autre tableau.

SELECT SUM([B].[TotalSale]) 
FROM [dbo].[BookingDetail] [BF] WITH (READPAST) 
INNER JOIN [dbo].[Booking] [B] WITH (READPAST) ON [B].[BookingDetailID] = [BF].[ID] 
WHERE [BF].[MarketID] = '2' 

Je souhaite ajouter une autre colonne pour obtenir la vente brute. Pour cela, je dois faire une jointure avec une autre table appelée AirTraveler.

Mais une fois que j'ajouter une nouvelle table à la requête

SELECT 
SUM([B].[TotalSale]) , 
SUM(CASE WHEN [B].[TravelSectorID] = 3 AND [B].[BookingStatusID] IN (16, 20, 22, 23) THEN COALESCE([B].[TotalSale], 0.0) 
     WHEN ([B].[TravelSectorID] = 1 AND [B].[IsDomestic] = 1 AND CONVERT(varchar, [AT].[FareDetails].query('string(/AirFareInfo[1]/PT[1])')) = 'FlightAndHotel') THEN [AT].[TotalSale] 
     ELSE 0 END) AS [GrossSale] 
FROM [dbo].[BookingDetail] [BF] WITH (READPAST) 
INNER JOIN [dbo].[Booking] [B] WITH (READPAST) ON [B].[BookingDetailID] = [BF].[ID] 
LEFT OUTER JOIN [dbo].[AirTraveler] [AT] WITH(READPAST) ON [B].[ID] = [AT].[BookingID] 
WHERE [BF].[MarketID] = '2' 

il donne un résultat incorrect de [TotalSale] .les fonctions d'agrégat renvoient des valeurs erronées, car il peut y avoir plusieurs AirTraveler par numéro de réservation, ce qui est correct . Que puis-je faire pour résoudre le problème de la fonction d'agrégation?

Je suis actuellement coincé. J'utilise SQL Server.

Merci d'avance.

+0

Sûrement votre le total est correct même avant cela parce que 'bookingdetail' a beaucoup de lignes ? Quoi qu'il en soit, la solution est d'utiliser 'WHERE EXISTS' plutôt que de se joindre. –

+0

@ Nick.McDermaid: en utilisant WHERE EXISTS, comment vais-je obtenir la valeur de [AT]. [FareDetails] .query ('string (/ AirFareInfo [1]/PT [1])'). Pourriez-vous s'il vous plaît modifier la requête susmentionnée. –

Répondre

0

n'a pas été testé ou quoi que ce soit, mais lorsque vous associez à une table de niveau inférieur qui provoque une table d'en-tête à double prise en compte, vous pouvez pré-agréger avant de rejoindre

Ceci est probablement manque des crochets d'ouverture/fermeture et les alias, mais nous espérons que vous pouvez travailler dehors

SELECT 
SUM([B].[TotalSale]) , 
SUM(CASE WHEN [B].[TravelSectorID] = 3 
AND [B].[BookingStatusID] IN (16, 20, 22, 23) 
THEN COALESCE([B].[TotalSale], 0.0) 
     WHEN ([B].[TravelSectorID] = 1 AND [B].[IsDomestic] = 1 
     THEN [AT].[TotalSale] 
     ELSE 0 END) AS [GrossSale] 
FROM [dbo].[BookingDetail] [BF] WITH (READPAST) 
INNER JOIN [dbo].[Booking] [B] WITH (READPAST) ON [B].[BookingDetailID] = [BF].[ID] 
LEFT OUTER JOIN 
(
SELECT BookingID, SUM(CASE WHEN 
CONVERT(varchar(50), [FareDetails].query('string(/AirFareInfo[1]/PT[1])')) 
= 'FlightAndHotel') THEN [TotalSale] ELSE 0 END) TotalSale 
FROM [dbo].[AirTraveler] [AT] WITH(READPAST) 
GROUP BY BookingID 
) AT 
ON [B].[ID] = [AT].[BookingID] 
WHERE [BF].[MarketID] = '2' 

aussi j'ai donné votre varchar jeté une taille - Je pense que si vous ne le faites pas, ce sera 1 si votre cas est jamais vrai