繁体   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