SQL Server如何将特定行的值转换为列值并关联对应行?
解决SQL Server中按顺序关联type='a'的值到type='b'行的问题
看起来你想要的是把每个type='b'的行,关联到它之前(按id顺序)最近的type='a'的value作为新列——这个需求确实没法直接用PIVOT实现,因为PIVOT是针对聚合行转列的场景,而这里是按顺序匹配最近的关联值,我们可以用窗口函数来搞定。
方法一:用分组关联实现
先给每一行标记分组,把每个a行和它后面的b行归为同一组,再通过分组关联取出a的value:
-- 先创建示例临时表(你可以替换成自己的表名) CREATE TABLE #temp ( machine INT, type VARCHAR(1), value DECIMAL(5,2), id INT ); INSERT INTO #temp VALUES (1, 'a', 0.34, 1), (1, 'b', 0.23, 2), (1, 'b', 0.26, 3), (1, 'b', 0.35, 4), (1, 'a', 0.15, 5), (1, 'b', 0.45, 6), (1, 'b', 0.55, 7); -- 核心查询 WITH grouped_data AS ( SELECT machine, type, value, id, -- 计算当前行及之前出现的'a'的次数,作为分组ID COUNT(CASE WHEN type = 'a' THEN 1 END) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS group_id FROM #temp ) SELECT g.machine, g.value, a.value AS value_col FROM grouped_data g JOIN grouped_data a ON g.group_id = a.group_id AND a.type = 'a' WHERE g.type = 'b' ORDER BY g.id;
方法二:用LAST_VALUE窗口函数更简洁
直接用LAST_VALUE函数,在窗口范围内取最近的a的value:
SELECT machine, value, -- 取当前行之前最后一个type='a'的value LAST_VALUE(CASE WHEN type = 'a' THEN value END) OVER ( ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS value_col FROM #temp WHERE type = 'b' ORDER BY id;
结果验证
两种方法都会返回你想要的结果:
| machine | value | value_col |
|---|---|---|
| 1 | 0.23 | 0.34 |
| 1 | 0.26 | 0.34 |
| 1 | 0.35 | 0.34 |
| 1 | 0.45 | 0.15 |
| 1 | 0.55 | 0.15 |
为什么PIVOT不适用?
PIVOT的核心是聚合行转列,比如把多个a行转成多列,但你的需求是把每个b行匹配到对应的a行值,属于按顺序的关联逻辑,不是聚合,所以PIVOT没法直接满足这个场景。
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

