Sql server SQL Server:如何用剩余的零值填充稀疏数据?
我有每个月和每个客户的销售数据报告。当我计算这些值时,由于sparsa数据格式的原因,不会报告零值 假设客户1-4。假设只有客户1-2有录音。直线表在行上有customerid,在列上有month,因此Sql server SQL Server:如何用剩余的零值填充稀疏数据?,sql-server,sql-server-2014,sparse-matrix,Sql Server,Sql Server 2014,Sparse Matrix,我有每个月和每个客户的销售数据报告。当我计算这些值时,由于sparsa数据格式的原因,不会报告零值 假设客户1-4。假设只有客户1-2有录音。直线表在行上有customerid,在列上有month,因此 |CustomerID|MonthID|Value| -------------------------| | 1 |201101 | 10 | | 2 |201101 | 100 | |CustomerID|201101|201102|2011103|...|2
|CustomerID|MonthID|Value|
-------------------------|
| 1 |201101 | 10 |
| 2 |201101 | 100 |
|CustomerID|201101|201102|2011103|...|201501|
---------------------------------------------
| 1 | 10 | 0 | 0 |...| 0 |
| 2 | 100 | 0 | 0 |...| 0 |
| 3 | 0 | 0 | 0 |...| 0 |
| 4 | 0 | 0 | 0 |...| 0 |
然后它们以交叉表格式报告,这样
|CustomerID|MonthID|Value|
-------------------------|
| 1 |201101 | 10 |
| 2 |201101 | 100 |
|CustomerID|201101|201102|2011103|...|201501|
---------------------------------------------
| 1 | 10 | 0 | 0 |...| 0 |
| 2 | 100 | 0 | 0 |...| 0 |
| 3 | 0 | 0 | 0 |...| 0 |
| 4 | 0 | 0 | 0 |...| 0 |
当我计算这些时,客户3-4没有得到任何东西,因为他们没有录音。我想得到丢失的零行。如何填充或选择原始数据并将不存在的零值填充到选择中?或者更简短地说:
处理稀疏数据格式并在最终报告中保持零客户的最优雅方式是什么?在转向交叉表格式之前,您将
交叉连接表客户和月,然后左连接表销售
select
c.CustomerId
, m.MonthId
, Value = isnull(s.Value,0)
from customers c
cross join months m
left join sales s
on s.CustomerId = c.CustomerId
and s.MonthId = m.MonthId
rextester演示:
返回:
+------------+---------+-------+
| CustomerId | MonthId | Value |
+------------+---------+-------+
| 1 | 201101 | 10 |
| 2 | 201101 | 100 |
| 3 | 201101 | 0 |
| 4 | 201101 | 0 |
| 1 | 201102 | 0 |
| 2 | 201102 | 0 |
| 3 | 201102 | 0 |
| 4 | 201102 | 0 |
| 1 | 201103 | 0 |
| 2 | 201103 | 0 |
| 3 | 201103 | 0 |
| 4 | 201103 | 0 |
+------------+---------+-------+
+-----------------------------------------------------------------------+
| CodeGenerated |
+-----------------------------------------------------------------------+
| select CustomerId, [201101],[201102],[201103] |
| from ( |
| select |
| c.CustomerId |
| , m.MonthId |
| , Value = isnull(s.Value,0) |
| from customers c |
| cross join months m |
| left join sales s |
| on s.CustomerId = c.CustomerId |
| and s.MonthId = m.MonthId |
| ) as t |
| pivot (sum([Value]) for [MonthId] in ([201101],[201102],[201103]) ) p |
+-----------------------------------------------------------------------+
向上面添加动态pivot()
,方法如下:
declare @cols nvarchar(max);
declare @sql nvarchar(max);
select @cols = stuff((
select ',' + quotename(MonthId)
from months
order by MonthId
for xml path (''), type).value('.','nvarchar(max)')
,1,1,'');
select @sql = '
select CustomerId, ' + @cols + '
from (
select
c.CustomerId
, m.MonthId
, Value = isnull(s.Value,0)
from customers c
cross join months m
left join sales s
on s.CustomerId = c.CustomerId
and s.MonthId = m.MonthId
) as t
pivot (sum([Value]) for [MonthId] in (' + @cols + ') ) p';
select @sql as CodeGenerated;
exec sp_executesql @sql;
返回:
+------------+---------+-------+
| CustomerId | MonthId | Value |
+------------+---------+-------+
| 1 | 201101 | 10 |
| 2 | 201101 | 100 |
| 3 | 201101 | 0 |
| 4 | 201101 | 0 |
| 1 | 201102 | 0 |
| 2 | 201102 | 0 |
| 3 | 201102 | 0 |
| 4 | 201102 | 0 |
| 1 | 201103 | 0 |
| 2 | 201103 | 0 |
| 3 | 201103 | 0 |
| 4 | 201103 | 0 |
+------------+---------+-------+
+-----------------------------------------------------------------------+
| CodeGenerated |
+-----------------------------------------------------------------------+
| select CustomerId, [201101],[201102],[201103] |
| from ( |
| select |
| c.CustomerId |
| , m.MonthId |
| , Value = isnull(s.Value,0) |
| from customers c |
| cross join months m |
| left join sales s |
| on s.CustomerId = c.CustomerId |
| and s.MonthId = m.MonthId |
| ) as t |
| pivot (sum([Value]) for [MonthId] in ([201101],[201102],[201103]) ) p |
+-----------------------------------------------------------------------+
而exec
返回:
+------------+--------+--------+--------+
| CustomerId | 201101 | 201102 | 201103 |
+------------+--------+--------+--------+
| 1 | 10 | 0 | 0 |
| 2 | 100 | 0 | 0 |
| 3 | 0 | 0 | 0 |
| 4 | 0 | 0 | 0 |
+------------+--------+--------+--------+