SQL如何实现行转列 将不同RowID的状态按维度合并为列展示
行转列实现方法
优先用条件聚合写法,全主流SQL数据库兼容,写法简单易维护,不会出现PIVOT常见的分组维度异常问题,可直接落地:
SELECT T.DateTime, T2.Node, T2.ID, MAX(CASE WHEN T.RowID = '1' THEN CASE WHEN T.Status LIKE 'StatusA%' THEN '1' WHEN T.Status LIKE 'StatusB%' THEN '2' WHEN T.Status LIKE 'StatusC%' THEN '3' WHEN T.Status LIKE 'StatusD%' THEN '4' WHEN T.Status LIKE 'StatusE%' THEN '5' WHEN T.Status LIKE 'StatusF' THEN '6' ELSE '0' END END) AS Row1Status, MAX(CASE WHEN T.RowID = '2' THEN CASE WHEN T.Status LIKE 'StatusA%' THEN '1' WHEN T.Status LIKE 'StatusB%' THEN '2' WHEN T.Status LIKE 'StatusC%' THEN '3' WHEN T.Status LIKE 'StatusD%' THEN '4' WHEN T.Status LIKE 'StatusE%' THEN '5' WHEN T.Status LIKE 'StatusF' THEN '6' ELSE '0' END END) AS Row2Status FROM Table1 T INNER JOIN Table2 T2 ON T2.ID = T.ID WHERE T.RowID IN ('1','2') GROUP BY T.DateTime, T2.Node, T2.ID
- 逻辑说明:按
DateTime、Node、ID三个维度分组,通过条件判断分别提取对应RowID的状态值,用MAX()聚合是因为分组后每个维度组合下,指定RowID的记录只会命中一次条件判断,其余记录返回NULL,MAX()会自动忽略NULL返回正确的状态值,不会出现计算偏差。 - 优化点:将原查询中
T.RowID = '1' or T.RowId = '2'的写法替换为T.RowID IN ('1','2'),执行效率更高。 - 扩展方式:后续如果需要新增RowID=3、RowID=4对应的状态列,只需要复制现有
MAX(CASE...)块,修改RowID判断条件和列别名即可。
如果需要使用PIVOT语法(仅支持SQL Server、Oracle等内置PIVOT算子的数据库),参考如下写法,之前PIVOT执行异常通常是因为没有提前裁剪基础数据的冗余列,PIVOT会默认将所有不在聚合、行转列配置中的列作为分组维度,多余列会导致分组结果不符合预期:
WITH BaseData AS ( SELECT T.DateTime, T2.Node, T2.ID, T.RowID, CASE WHEN T.Status LIKE 'StatusA%' THEN '1' WHEN T.Status LIKE 'StatusB%' THEN '2' WHEN T.Status LIKE 'StatusC%' THEN '3' WHEN T.Status LIKE 'StatusD%' THEN '4' WHEN T.Status LIKE 'StatusE%' THEN '5' WHEN T.Status LIKE 'StatusF' THEN '6' ELSE '0' END AS ActualStatus FROM Table1 T INNER JOIN Table2 T2 ON T2.ID = T.ID WHERE T.RowID IN ('1','2') ) SELECT DateTime, Node, ID, [1] AS Row1Status, [2] AS Row2Status FROM BaseData PIVOT( MAX(ActualStatus) FOR RowID IN ([1],[2]) ) AS PivotResult
内容的提问来源于stack exchange,提问作者BaldFeegle
相关产品推荐
相关产品推荐

