SQL Server:如何用可变数据填充临时表列并合并同日期行?
解决多PDN行合并与过滤的SQL方案
核心需求拆解
先把你的需求捋清楚:
- 涉及两张表
e和p - 必须过滤掉两类PDN:
p.hours = 0的记录,以及在p表中完全不存在的PDN - 需要把
p.eventdate相同的不同PDN行合并成同一行(本质是行转列,把不同PDN作为单独列展示) - 单日期最多会出现10种PDN,全量共有39种不同PDN
具体实现方案
这类行转列+过滤的需求,用条件聚合是最直接的方案,结合JOIN和WHERE子句就能搞定。
参考SQL代码
假设表e包含日期字段eventdate,表p包含eventdate、pdn、hours三个核心字段,以下是可直接参考的查询语句:
SELECT e.eventdate, -- 按PDN逐个生成列,这里示例写3个,你可以扩展到需要的10种 MAX(CASE WHEN p.pdn = 'PDN001' THEN p.hours END) AS PDN001_hours, MAX(CASE WHEN p.pdn = 'PDN002' THEN p.hours END) AS PDN002_hours, MAX(CASE WHEN p.pdn = 'PDN003' THEN p.hours END) AS PDN003_hours, -- ... 继续添加到你需要的第10种PDN的CASE语句 MAX(CASE WHEN p.pdn = 'PDN010' THEN p.hours END) AS PDN010_hours FROM e LEFT JOIN p ON e.eventdate = p.eventdate WHERE -- 过滤掉hours为0的记录,同时确保PDN是存在的 p.hours > 0 AND p.pdn IS NOT NULL GROUP BY e.eventdate ORDER BY e.eventdate;
关键逻辑说明
- 过滤规则:
WHERE p.hours > 0 AND p.pdn IS NOT NULL直接排除了无效的PDN记录,确保只有有有效时长的PDN才会被纳入结果 - 行转列实现:
MAX(CASE WHEN ...)把同一日期下不同PDN的行数据转换成列,用MAX是因为每个eventdate+pdn组合应该只有一行数据,聚合后刚好能取出对应的hours值 - 灵活调整:如果需要展示全量39种PDN(当天没有数据的话显示NULL),只需要把所有PDN的CASE语句都补充进去就行;如果不需要保留没有有效PDN的日期行,可以把
LEFT JOIN改成INNER JOIN
额外提示
如果PDN的种类是动态变化的,不想手动写所有CASE语句,可以用对应数据库的动态SQL生成逻辑(比如MySQL用PREPARE语句,SQL Server用EXEC动态拼接),不过这种场景下固定写10个CASE更简单直接。
内容的提问来源于stack exchange,提问作者Green
相关产品推荐
相关产品推荐

