You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL员工缺勤透视表(Pivot)中过滤NULL值?

解决SQL透视表中NULL/空值的问题

你的问题根源很明确:源数据里存在Bezeichnung为空的记录,在透视后这些空值就转化成了NULL。下面给你三种针对性的解决方案,根据你的实际需求选择:

方案1:从源数据过滤空值(推荐)

如果这些Bezeichnung为空的记录本身就不需要出现在结果里,最直接的方式是在子查询中提前过滤掉它们。修改动态SQL里的子查询部分,加入对Bezeichnung的非空判断:

DECLARE @columns NVARCHAR(MAX) = '', @sql NVARCHAR(MAX) = '';

-- 保持列名生成逻辑不变
SELECT @columns = STUFF((SELECT ',' + QUOTENAME(Datum) 
                         FROM (SELECT DISTINCT Datum FROM table1 WHERE Datum > DATEADD(day, -1, GETDATE()) AND Datum < DATEADD(day, +13, GETDATE())) sub 
                         ORDER BY Datum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

-- 修改子查询,过滤空的Bezeichnung
SET @sql =' 
SELECT * 
FROM ( 
    SELECT DISTINCT Vorname, Nachname, Bezeichnung, datum 
    FROM table1 a 
    LEFT JOIN table2 b ON a.Mitarbeiter_ID = b.Mitarbeiter_ID
    -- 过滤掉Bezeichnung为NULL或空字符串的行
    WHERE ISNULL(b.Bezeichnung, '''') <> ''''
) t 
PIVOT (MAX(Bezeichnung) FOR datum IN ('+ @columns +') ) AS pivot_table;';

EXECUTE sp_executesql @sql;

这样一来,只有Bezeichnung有有效值的记录会被纳入透视,结果里自然不会出现NULL。

方案2:将NULL替换为空字符串或自定义文本

如果你需要保留行,但不想显示NULL,可以在动态生成的列中用ISNULL或COALESCE把NULL替换成空字符串(或者你想要的文本,比如'-')。需要修改列名的生成逻辑:

DECLARE @columns NVARCHAR(MAX) = '', @sql NVARCHAR(MAX) = '';

-- 修改列生成逻辑,给每个列套上ISNULL处理
SELECT @columns = STUFF((SELECT ', ISNULL(' + QUOTENAME(Datum) + ', '''') AS ' + QUOTENAME(Datum) 
                         FROM (SELECT DISTINCT Datum FROM table1 WHERE Datum > DATEADD(day, -1, GETDATE()) AND Datum < DATEADD(day, +13, GETDATE())) sub 
                         ORDER BY Datum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

-- 提取原始列名用于PIVOT的IN子句
DECLARE @pivot_columns NVARCHAR(MAX) = REPLACE(REPLACE(@columns, 'ISNULL(', ''), ', '''') AS ', ', ')

-- 动态SQL中选择处理后的列,而非直接SELECT *
SET @sql =' 
SELECT Vorname, Nachname, ' + @columns + '
FROM ( 
    SELECT DISTINCT Vorname, Nachname, Bezeichnung, datum 
    FROM table1 a LEFT JOIN table2 b ON a.Mitarbeiter_ID = b.Mitarbeiter_ID
) t 
PIVOT (MAX(Bezeichnung) FOR datum IN ('+ @pivot_columns +') ) AS pivot_table;';

EXECUTE sp_executesql @sql;

这个方案会把所有NULL值替换成空字符串,结果看起来更整洁。

方案3:过滤透视后全为NULL的行

如果你的需求是保留有至少一个有效日期值的行,过滤掉所有日期列都是NULL的行,可以在透视后加WHERE条件:

DECLARE @columns NVARCHAR(MAX) = '', @sql NVARCHAR(MAX) = '';

SELECT @columns = STUFF((SELECT ',' + QUOTENAME(Datum) 
                         FROM (SELECT DISTINCT Datum FROM table1 WHERE Datum > DATEADD(day, -1, GETDATE()) AND Datum < DATEADD(day, +13, GETDATE())) sub 
                         ORDER BY Datum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

-- 生成COALESCE条件,只要有一个列不为NULL就保留该行
DECLARE @filter NVARCHAR(MAX) = 'COALESCE(' + REPLACE(@columns, ', ', ', ') + ') IS NOT NULL';

SET @sql =' 
SELECT * 
FROM ( 
    SELECT DISTINCT Vorname, Nachname, Bezeichnung, datum 
    FROM table1 a LEFT JOIN table2 b ON a.Mitarbeiter_ID = b.Mitarbeiter_ID
) t 
PIVOT (MAX(Bezeichnung) FOR datum IN ('+ @columns +') ) AS pivot_table
WHERE ' + @filter + ';';

EXECUTE sp_executesql @sql;

这个方案会剔除那些在所有日期列都没有有效Bezeichnung的行。

内容的提问来源于stack exchange,提问作者BM-SMS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:07:38