SQL Server行转列查询仅返回单条数据,求修正方法
SQL Server行转列问题:如何生成多条目标记录?
我看了你遇到的行转列问题,当前查询只返回了一条记录,没生成第二条符合要求的结果,问题出在缺少分组依据上,我来给你拆解下修改方案:
输入表(ABC)
COL_NAME COL_VALUE FLAG --------------------------- COL_1 100 N COL_2 RAM N COL_3 KOL N COL_1 345 N COL_2 SAM N COL_3 DEL N COL_1 348 Y COL_2 TAM Y COL_3 MUM Y
期望输出表(XYZ)
COL_1 COL_2 COL_3 FLAG ----------------------------- 100 RAM KOL N 345 SAM DEL N
当前查询的问题
你当前的查询没有指定分组逻辑,MAX()函数会把所有FLAG='N'的行聚合为一个组,自然只会返回一条记录。要生成两条独立的结果,我们需要给每一组对应的COL_1/COL_2/COL_3分配一个组标识,让SQL知道哪些行属于同一批次。
修改后的查询语句
我们可以用窗口函数ROW_NUMBER()来生成组标识,然后基于这个标识分组行转列:
IF (SELECT COUNT(*) FROM ABC WHERE FLAG='N') > 0 BEGIN -- 先给每组数据添加组ID WITH GroupedABC AS ( SELECT COL_NAME, COL_VALUE, FLAG, -- 按FLAG和COL_NAME分组,给每个批次分配相同的组ID ROW_NUMBER() OVER (PARTITION BY FLAG, COL_NAME ORDER BY (SELECT NULL)) AS GroupId FROM ABC WHERE FLAG = 'N' -- 只处理FLAG为N的记录 ) -- 基于组ID进行行转列并插入到XYZ INSERT INTO XYZ SELECT MAX(CASE WHEN COL_NAME='COL_1' THEN COL_VALUE END) AS COL_1, MAX(CASE WHEN COL_NAME='COL_2' THEN COL_VALUE END) AS COL_2, MAX(CASE WHEN COL_NAME='COL_3' THEN COL_VALUE END) AS COL_3, FLAG FROM GroupedABC GROUP BY GroupId, FLAG; -- 按组ID和FLAG分组,确保每组生成一条记录 END
为什么这样修改?
ROW_NUMBER() OVER (PARTITION BY FLAG, COL_NAME ORDER BY (SELECT NULL))会给FLAG='N'下的每一个COL_NAME行分配递增的序号,比如前三个N的行(COL_1/COL_2/COL_3)的GroupId都是1,接下来三个N的行GroupId都是2,这样就把数据分成了两个独立的组。- 之后通过
GROUP BY GroupId, FLAG分组,再用MAX()函数提取每个组中对应COL_NAME的取值,就能生成两条符合要求的记录了。
内容的提问来源于stack exchange,提问作者Erico




