Суммирование значений из нескольких таблиц, сгруппированных по общему столбцу - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть три таблицы в MS SQL Server 2014. Каждая из них содержит пару числовых значений, описание и дату.Для краткости, давайте предположим, что следующие таблицы:

table "beverages"

day        beverage amount
---------- -------- ------
2018-12-01 water    2
2018-12-01 tea      1
2018-12-01 coffee   7
2018-12-02 water    4
2018-12-02 tea      2


table "meals"

day        meal   amount
---------- ------ ------
2018-12-01 burger 1
2018-12-01 bread  2
2018-12-02 steak  1


table "fruit"

day        fruit  amount
---------- ------ ------
2018-12-01 apple  4
2018-12-01 banana 1
2018-12-02 apple  2

Тогда у меня есть другая таблица, содержащая только список дат.

table "dates"

day
----------
2018-12-01
2018-12-02

Мне нужен запрос, который возвращаетпо одной строке для каждой строки в таблице dates, и в каждой строке указана дата, общее количество напитков, общее количество приемов пищи и общее количество фруктов за этот день.Меня не волнуют разные виды напитков, блюд и фруктов, только сумма.Результат должен быть:

expected result

day        beverages   meals       fruit
---------- ----------- ----------- -----------
2018-12-01 10          3           5
2018-12-02 6           1           2 

Но вместо этого я получаю

received result

day        beverages   meals       fruit
---------- ----------- ----------- -----------
2018-12-01 40          18          30
2018-12-02 6           2           4

Я уже знаю, в чем проблема, просто не как ее исправить.Хуже того, я уверен, что когда-то знал ответ, но теперь я даже не могу подобрать правильные условия поиска, чтобы заставить Google сказать мне ...

Когда я делаю такой запрос (я использовалпеременные таблицы для тестирования)

SELECT 
     [d].[day]
    ,SUM([b].[amount]) AS [beverages]
    ,SUM([m].[amount]) AS [meals]
    ,SUM([f].[amount]) AS [fruit]
FROM @dates AS [d]
LEFT OUTER JOIN @beverages AS [b]
    ON [d].[day] = [b].[day]
LEFT OUTER JOIN @meals AS [m]
    ON [d].[day] = [m].[day]
LEFT OUTER JOIN @fruit AS [f]
    ON [d].[day] = [f].[day]
GROUP BY [d].[day]

он суммирует каждую строку из разных таблиц более одного раза, поскольку возвращает каждую возможную комбинацию из трех таблиц.Удаление SUM () и GROUP BY доказывает, что:

day        beverages   meals       fruit
---------- ----------- ----------- -----------
2018-12-01 2           1           4
2018-12-01 2           1           1
2018-12-01 2           2           4
2018-12-01 2           2           1
2018-12-01 1           1           4
2018-12-01 1           1           1
2018-12-01 1           2           4
2018-12-01 1           2           1
2018-12-01 7           1           4
2018-12-01 7           1           1
2018-12-01 7           2           4
2018-12-01 7           2           1
2018-12-02 4           1           2
2018-12-02 2           1           2

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

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Сгруппируйте таблицы перед объединением следующим образом:

SELECT 
     [d].[day]
    ,[b].[amount] AS [beverages]
    ,[m].[amount] AS [meals]
    ,[f].[amount] AS [fruit]
FROM @dates AS [d]
LEFT OUTER JOIN (SELECT day, SUM(amount) as amount FROM @beverages GROUP BY day) AS [b]
    ON [d].[day] = [b].[day]
LEFT OUTER JOIN (SELECT day, SUM(amount) as amount FROM @meals GROUP BY day) AS [m]
    ON [d].[day] = [m].[day]
LEFT OUTER JOIN (SELECT day, SUM(amount) as amount FROM @fruit GROUP BY day) AS [f]
    ON [d].[day] = [f].[day]
0 голосов
/ 13 декабря 2018

Как насчет PIVOT вместо этого?

Пример

Select *
 From (
        Select day,Item='beverage',amount from beverages
        Union All
        Select day,Item='meals'   ,amount from meals
        Union All
        Select day,Item='fruit'   ,amount from fruit
      ) src
Pivot ( sum(amount) for Item in ([beverages],[meals],[fruit]) ) pvt
...