簡體   English   中英

帶有join,sum,group by等的SQL查詢

[英]SQL query with join, sum, group by, etc

我正在嘗試構建一個如下所示的報告:

      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_itemt_value t_item有2列: itemIDitemName t_value有3列: itemIDvaluedate

通過以下查詢,我可以生成包含所有itens的列表,即使是空列表也是如此。

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)

有可能嗎? 如何在結果中包含沒有值和組的itens,然后按月包含?

TIA,

短發

對於數據中的“漏洞”,您需要一個填充表。 使用完整的外部聯接將此表連接到月份的事實表。

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

對於格式化,您有幾種選擇。

  • 在報告工具中使用交叉表或矩陣函數。
  • 在SQL中使用CASE函數。
  • 在SQL中使用Pivot函數。

您是否正在使用具有交叉表功能的報告工具?

如果沒有,您可以為每個月創建一個總和列。 所以你的結果集實際上看起來像那個報告樣本。

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

這是一個例子:

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,其中特定項目未被出售。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM