【问题标题】:How to get rid of null value table A left outer join pivot table如何摆脱空值表左外连接数据透视表
【发布时间】:2015-12-18 22:04:23
【问题描述】:

我想在结果表中将那些 NULL 值设置为零。到目前为止我找不到任何解决方案。

(A)

CREATE TABLE ##Temp1
 (
    tmp_id varchar(8),
    tmp_ac varchar(5),
    tmp_amt decimal(15,2)
 )

Record :
id   ac      amt
1    30100   100.00
2    30400   300.00
3    30500   500.00

(B) 创建动态列数据透视表:

declare @cols as varchar(max)
declare @query as varchar(max)

select @cols = ISNULL(@cols + ',','') + '[' + tmp_ac + ']' from ##Temp1 order by tmp_ac 

set @query = 'select tmp_id, '+ @cols + ' into ##TempPV from 
              (
                  select tmp_id, tmp_ac, isnull(tmp_amt,0) as tmp_amt
                  from ##Temp1
              ) x
              pivot
              (
                 sum(tmp_amt)
                  for tmp_ac in (' + @cols + ')
              ) p'
exec (@query)

(C)左外连接表 A 到表主元:

select
 ##TempA.f_id  as [ID],
##TempPV.*          
from ##TempA
left outer join  ##TempPV
on  ##TempA.f_id = tmp_id
order by f_id

(D) 结果:

Id   30100    30400    30500
1    100.00   NULL     NULL
2    NULL     300.00   NULL
3    NULL     NULL     500.00
4    NULL     NULL     NULL
5    NULL     NULL     NULL

(E) 预期结果:

Id   30100    30400    30500
1    100.00   0.00     0.00
2    0.00     300.00   0.00
3    0.00     0.00     500.00
4    0.00     0.00     0.00
5    0.00     0.00     0.00

【问题讨论】:

  • 由于 ID 的原因,当您使用 ID 加入它们时,我们会得到空值
  • 我必须包含来自##TempA 的所有记录。这就是为什么我必须显示 ##TempA 中的所有 Id。
  • id 4 和 5 来自哪里?
  • 假设 ##TempA 预先包含 ID“1”、“2”、“3”、“4”、“5”。
  • 所以你想要...选择##TempA.f_id 作为[ID]、ISNULL(##TempPV.[30100], 0) 等?但列名是动态的,例如使用@cols?

标签: sql-server


【解决方案1】:

您必须在主 SELECT 中使用 coalesce(或 isnull)。 我还添加了一个带有 tempA 和 5 个 ID 的 LEFT JOIN。

查询:

declare @col_null as varchar(max)
declare @cols as varchar(max)
declare @query as varchar(max)

select @col_null = ISNULL(@col_null + ',','') + ' ['+tmp_ac+ '] = coalesce([' + tmp_ac + '], 0)' from #Temp1 order by tmp_ac 
select @cols = ISNULL(@cols + ',','') + ' [' + tmp_ac + ']' from #Temp1 order by tmp_ac 

set @query = 'select id, '+ @col_null + ' /*into #TempPV*/ from 
              (
                  select id, tmp_ac, isnull(tmp_amt,0) as tmp_amt
                  from #tempA ta
                  LEFT JOIN #Temp1 t1 ON ta.id = t1.tmp_id

              ) x
              pivot
              (
                 sum(tmp_amt)
                  for tmp_ac in (' + @cols + ')
              ) p'

您必须使用第二个列列表,因为枢轴只需要列名,并且您的 SELECT 必须是这样的:[30400] = coalesce([30400], 0)

输出:

id  30100   30400   30500
1   100.00  0.00    0.00
2   0.00    300.00  0.00
3   0.00    0.00    500.00
4   0.00    0.00    0.00
5   0.00    0.00    0.00

数据:

CREATE TABLE #Temp1
(
    tmp_id varchar(8),
    tmp_ac varchar(5),
    tmp_amt decimal(15,2) 
)

INSERT INTO #Temp1(tmp_id, tmp_ac, tmp_amt) values
    (1, 30100, 100.00)
    , (2, 30400, 300.00)
    , (3, 30500, 500.00)

CREATE TABLE #TempA(id varchar(8));
INSERT INTO #tempA(id) values (1), (2), (3), (4), (5);

【讨论】:

  • 非常感谢朱利安!这是工作! :) 顺便说一句,是否有任何其他方法可以使 Id“4”和“5”显示为零,即使在 Pivot Temp 文件中找不到它们?因为我必须显示主表中的所有 Id (##TempA)。
【解决方案2】:

不确定这是否可行,但我正在尝试构建查询 (C) 并动态添加列名,并在它们周围添加 ISNULL()...

(C) 左外连接表 A 到表主元:

declare @cols2 as varchar(max)
select @cols2 = ISNULL(@cols2 + ',','') + 'ISNULL(##TempPV.[' + tmp_ac + '], 0) as [' + tmp_ac + ']' from ##Temp1 order by tmp_ac 

set @query2 = 'select
               ##TempA.f_id  as [ID],
               ' + @cols2 + '          
               from ##TempA
               left outer join  ##TempPV
               on  ##TempA.f_id = tmp_id
               order by f_id'

exec (@query2)

【讨论】:

  • 非常感谢 Quantumplate!根据您的想法,我终于解决了我的问题。 ;)
  • 很高兴它很有用 :) 您应该强调您的最终解决方案是帮助他人,例如如果提供的答案均未按原样工作,请创建一个新答案并标记为正确。
猜你喜欢
  • 2018-04-06
  • 2017-07-16
  • 2016-01-11
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多