如何使用UNPIVOT转换宽表为长表且避免数据重复?
问题分析与解决方案
你当前用两次UNPIVOT的方式会产生笛卡尔积——第一次把日期拆成2条记录,第二次把金额拆成2条记录,两者组合后每条原始行会生成4条记录,导致日期和金额无法正确配对。
要实现目标表的效果,不需要多次UNPIVOT,以下两种方法可以正确转换且不丢失数据关联:
方法一:使用UNION ALL(通用SQL语法)
直接将每组日期和金额分别查询后合并,逻辑简单易懂,兼容绝大多数数据库:
SELECT METERNUM, READDATETME1 AS READDATETME, READAMOUNT1 AS READAMOUNT FROM SMARTMETER WHERE READDATETME1 IS NOT NULL -- 可选,过滤无日期的无效记录 UNION ALL SELECT METERNUM, READDATETME2 AS READDATETME, READAMOUNT2 AS READAMOUNT FROM SMARTMETER WHERE READDATETME2 IS NOT NULL -- 可选,过滤无日期的无效记录 ORDER BY METERNUM, READDATETME;
方法二:使用CROSS APPLY + VALUES(适用于SQL Server、Azure SQL等)
通过CROSS APPLY将每行的两组日期金额转为多行,始终保持对应关系:
SELECT METERNUM, ca.READDATETME, ca.READAMOUNT FROM SMARTMETER CROSS APPLY ( VALUES (READDATETME1, READAMOUNT1), (READDATETME2, READAMOUNT2) ) ca(READDATETME, READAMOUNT) WHERE ca.READDATETME IS NOT NULL -- 过滤空记录 ORDER BY METERNUM, ca.READDATETME;
这两种方法都能得到你想要的目标表结构,确保每条日期和对应的金额正确关联,不会出现数据失真的情况。
内容的提问来源于stack exchange,提问作者Garrett Jones
相关产品推荐
相关产品推荐

