2015-11-02 4 views
1

Я, похоже, не могу обдумать вопрос о правильном запросе этого вопроса. У меня есть три таблицы и вы хотите объединить их, чтобы показать, сколько билетов осталось в каждом месте. Я запускаю SQL Server 2008 R2.Запрос, который объединяет три таблицы, чтобы показать общее количество

Местоположение Таблица

LocationId | LocationName 
1   | Location1 
2   | Location2 
3   | Location3 

Билеты в местоположение Таблица

TicketId | LocationId | EventId | Amount 
1  | 1   | 4  | 25 
1  | 2   | 4  | 50 
1  | 3   | 4  | 100 

Приобретенные билеты Таблица

AttendeeId | EventId | TicketId | LocationId | Amount | EmployeeId 
1   | 4  | 1  | 1   | 5  | 101 
2   | 4  | 1  | 1   | 10  | 102 
3   | 4  | 1  | 2   | 2  | 103 
4   | 4  | 1  | 2   | 4  | 103 

Я хочу, чтобы запрос, чтобы отобразить три таблицы, как это:

LocationName | Starting | Sold | Remaining 
Location1 | 25  | 15 | 10 
Location2 | 50  | 6 | 44 
Location3 | 100  | 0 | 0 

Это вопрос, с которым я играл, но он показывает мне только те места, где были проданы билеты, мне нужно, чтобы они показывали мне все места, даже если у них нет билетов.

SELECT L.LocationName, T.Amount as Starting, COALESCE(SUM(P.Amount),0) as Sold, COALESCE((T.Amount - SUM(P.Amount)),0) as Remaining 
FROM TicketsPerLocation T 
LEFT JOIN Locations L 
ON T.LocationId = L.LocationId 
LEFT JOIN PurchasedTickets P 
ON T.LocationId = P.LocationId 
WHERE T.TicketId = 1 AND T.EventId = 4 AND P.TicketId = 1 
GROUP BY L.Name, T.Amount, T.TicketId 

ответ

1

Вам нужно перемещать таблицы вокруг немного ..

SELECT l.LocationName, 
     tpl.Amount, 
     COALESCE(SUM(pt.Amount),0) Sold, 
     tpl.Amount - COALESCE(SUM(pt.Amount),0) Remaining 
FROM Locations l 
     INNER JOIN TicketsPerLocation tpl ON l.LocationID = tpl.LocationID 
     LEFT JOIN PurchasedTickets pt ON tpl.TicketID = pt.TicketID 
      AND tpl.LocationID = pt.LocationID 
      AND tpl.EventID = pt.EventID 
WHERE tpl.TicketID = 1 AND tpl.EventID = 4 
GROUP BY l.LocationName, 
     tpl.Amount 

плюс ваше где заявление было P.TicketId = 1, что делает что INNER JOIN вместо LEFT JOIN .. так что удалить.

, когда вы присоединитесь к PurchasedTickets, убедитесь, что он на все поля, которые связаны с TicketsPerLocation и не только Место

SQL Fiddle

0

Я вижу несколько проблем в запросе. Смотрите, если фиксируя это решает ее:

  1. Так как вы хотите, чтобы все места, вы должны начать с этой таблицей перед LEFT JOIN, а не после него.

  2. Таблица купленных билетов - внешнее соединение, но у вас оно есть в вашем месте where. Это всегда плохая комбинация, потому что эти две вещи противоречат друг другу. Я бы переместил это требование в предложение ON.

 
    SELECT L.LocationName 
     ,T.Amount AS Starting 
     ,COALESCE(SUM(P.Amount), 0) AS Sold 
     ,COALESCE((T.Amount - SUM(P.Amount)), 0) AS Remaining 
    FROM Locations L 
    LEFT JOIN TicketsPerLocation T ON T.LocationId = L.LocationId 
    LEFT JOIN PurchasedTickets P ON T.LocationId = P.LocationId 
     AND P.TicketId = 1 
    WHERE T.TicketId = 1 
     AND T.EventId = 4 
    GROUP BY L.NAME 
     ,T.Amount 
     ,T.TicketId 
0
SELECT L.LocationName, T.Amount as Starting, ISNULL(p.SumAmt,0) As Sold, T.Amount - ISNULL(p.SumAmt,0) AS Remaining 
FROM Locations L 
LEFT JOIN TicketsPerLocation T 
    ON T.LocationId = L.LocationId AND T.TicketId = 1 AND T.EventId = 4 
LEFT JOIN 
    (SELECT [EventId], [TicketId], [LocationId], SUM(Amount) AS SumAmt 
    FROM PurchasedTickets 
    GROUP BY [EventId], [TicketId], [LocationId] 
    ) p 
    ON T.LocationId = P.LocationId 
    AND P.TicketId = T.TicketId AND P.EventId = T.EventId 
ORDER BY L.LocationName 

SQL Fiddle