SQL-запрос с объединением, суммой, группировкой и т. Д. - PullRequest
1 голос
/ 28 марта 2009

Я пытаюсь создать отчет, который будет выглядеть так:

      jan feb mar apr may jun jul ago sep oct nov dec
food   0   1   1   2   0   0   3   1   0   0   1   1
car    1   0   0   0   1   2   1   0   1   2   3   4
home   0   0   1   2   2   2   5   1   2   4   0   0
other  0   0   0   0   0   0   0   0   0   0   0   0

У меня есть две таблицы: t_item и t_value. t_item имеет 2 столбца: itemID и itemName. t_value имеет 3 столбца: itemID, value, date.

С помощью следующего запроса я могу создать список со всеми символами, даже с пустыми.

SELECT t_item.itemID, ISNULL(SUM(t_value.value), 0) AS value
FROM t_value RIGHT OUTER JOIN t_item ON t_value.itemID = t_item.itemID
GROUP BY t_item.itemID

Но, если я попытаюсь включить столбец MONTH (как показано ниже), результат покажет только элементы со значениями ...

SELECT t_item.itemID, ISNULL(SUM(t_value.value), 0) AS value, MONTH(date) AS date
FROM t_value RIGHT OUTER JOIN t_item ON t_value.itemID = t_item.itemID
GROUP BY t_item.itemID, MONTH(date)

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

ТИА

Bob

Ответы [ 4 ]

1 голос
/ 28 марта 2009
WITH    calendar(mon) AS
        (
        SELECT  1
        UNION ALL
        SELECT  mon + 1
        FROM    calendar
        WHERE   mon < 12
        )
SELECT  itemID, mon, SUM(value)
FROM    calendar c, t_item i
LEFT OUTER JOIN
        t_value v
ON      v.itemID = i.itemID
        AND MONTH(date) = mon
GROUP BY
        i.itemID, mon
1 голос
/ 28 марта 2009

Используете ли вы инструмент отчетности с возможностью кросс-таблицы?

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

SELECT t_item.itemID, 

--ISNULL(SUM(t_value.value), 0) AS value, 

sum(case when MONTH(date) = 1 then t_value.value else 0 end) AS m1_sum,
sum(case when MONTH(date) = 2 then t_value.value else 0 end) AS m2_sum,
sum(case when MONTH(date) = 3 then t_value.value else 0 end) AS m3_sum,
--etc

FROM t_value RIGHT OUTER JOIN t_item ON t_value.itemID = t_item.itemID
GROUP BY t_item.itemID
1 голос
/ 28 марта 2009

Вот пример:

create table #months (value int, name varchar(12))
create table #items (value int, name varchar(24))
create table #sales (month int, item int, sales int)

insert into #months values (1, 'jan')
insert into #months values (2, 'feb')
insert into #months values (3, 'mar')

insert into #items values (1, 'apple')
insert into #items values (2, 'pear')
insert into #items values (3, 'nut')

insert into #sales values (1,1,12)
insert into #sales values (2,2,3)
insert into #sales values (2,2,5)
insert into #sales values (3,3,7)

Вы можете запросить его, используя таблицу PIVOT, например:

select *
from (
    select
        item = #items.name
    ,   month = #months.name
    ,   sales = isnull(sum(#sales.sales),0)
    from #months
    cross join #items
    left join #sales on #months.value = #sales.month 
         and #items.value = #sales.item
    group by #months.name, #items.name
) vw
pivot (sum(sales) for month in ([jan],[feb],[mar])) as PivotTable

Или, в качестве альтернативы, обычный запрос:

select
    item = #items.name
,   jan = sum(case when #sales.month = 1 then sales else 0 end)
,   feb = sum(case when #sales.month = 2 then sales else 0 end)
,   mar = sum(case when #sales.month = 3 then sales else 0 end)
from #items
left join #sales on #items.value = #sales.item
group by #items.name

Оба результата:

item        jan     feb     mar
apple       12      0       0
nut         0       0       7
pear        0       8       0

В первом примере «перекрестное соединение» обеспечивает наличие всех месяцев и значений. Затем они «соединяются влево», поэтому отображаются даже строки без значений.

Функция IsNull () предназначена для отображения 0 вместо NULL в течение месяца, в течение которого данный конкретный элемент не был продан.

1 голос
/ 28 марта 2009

Для «дыр» в ваших данных вам нужна таблица заполнителей. Присоединитесь к этой таблице с помощью полного внешнего соединения с таблицей фактов за месяц.

month
------
month --values jan through dec

Для форматирования у вас есть пара вариантов.

  • В вашем инструменте отчетности используйте функцию кросс-таблицы или матрицы.
  • В SQL используйте функцию CASE.
  • В SQL используйте функцию Pivot.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...