我正在尝试构建一个如下所示的报告:
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
有两列:itemID
和itemName
。 t_value
有3列:itemID
,value
,date
。
使用以下查询,我可以生成包含所有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,
鲍勃
答案 0 :(得分:1)
对于数据中的“漏洞”,您需要一个填充表。使用完整的外部联接将该表连接到月份的事实表。
month
------
month --values jan through dec
对于格式化,您有几种选择。
答案 1 :(得分:1)
您是否正在使用具有交叉布功能的报告工具?
如果没有,您可以为每个月创建一个总和列。所以你的结果集实际上看起来就像那个报告样本。
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
答案 2 :(得分:1)
以下是一个例子:
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。
答案 3 :(得分:1)
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