你有一个场景,我已经做了这样的SQL查询输出:
number x1 y1 z1 x2 y2 z2 x3 y3 z3
a 1 10 aa
a 2 8 aa
a 3 6 aa
b 4 11 bb
b 5 6 bb
现在我被困在这里:如何将上述行转换为:
number x1 y1 z1 x2 y2 z2 x3 y3 z3
a 1 10 aa 2 8 aa 3 6 aa
b 4 11 bb 5 6 bb
每个数字最多可包含10个x_,y_,z_values(x1,y1,z1,...,x10,y10,z10)
那怎么能实现呢?
答案 0 :(得分:0)
我不知道这背后的逻辑是什么,但是可以做到。
首先,我使用它来初始化您作为测试集提供的相同数据:
CREATE TABLE TESTTABLE (number varchar(5), x1 varchar(5), y1 varchar(5), z1 varchar(5)
, x2 varchar(5), y2 varchar(5), z2 varchar(5), x3 varchar(5), y3 varchar(5), z3 varchar(5))
INSERT INTO TESTTABLE (number,x1,y1,z1)
VALUES ('a','1','10','aa')
,('a','2','8','aa')
,('a','3','6','aa')
,('b','4','11','bb')
,('b','5','6','bb')
现在查询..如果您通过硬编码最大列数来冷却,您可以选择以下内容:
;WITH CTE AS
(SELECT ROW_NUMBER() OVER (PARTITION BY number ORDER BY x1 asc) RN, *
FROM TESTTABLE)
SELECT c.number, C.x1, C.y1, C.z1
, C2.x1 as x2, C2.y1 as y2, C2.z1 as z2
, C3.x1 as x3, C3.y1 as y3, C3.z1 as z3
FROM CTE C
LEFT JOIN CTE C2 ON C2.number = C.number AND C2.RN = 2
LEFT JOIN CTE C3 ON C3.number = C.number AND C3.RN = 3
WHERE C.RN=1
但是,如果你想动态只显示有数据的列,那么就可以完成这项任务(这很难看,但我唯一担心的是它可以工作:)。
DECLARE @TSQLHeader nvarchar(max) = '', @TSQLTrailer nvarchar(max) = '
FROM CTE C'
DECLARE @MaxCols INT =
(SELECT TOP 1 COUNT(*) CNT FROM TESTTABLE GROUP BY number ORDER BY CNT DESC)
, @CurCol INT = 2
SELECT @TSQLHeader =
';WITH CTE AS
(SELECT ROW_NUMBER() OVER (PARTITION BY number ORDER BY x1 asc) RN, *
FROM TESTTABLE)
SELECT c.number, C.x1, C.y1, C.z1'
WHILE @CurCol <= @MaxCols
BEGIN
SELECT @TSQLHeader = @TSQLHeader+'
, C'+CAST(@CurCol AS VARCHAR(5))+'.x1 as x'+CAST(@CurCol AS VARCHAR(5))+', C'+CAST(@CurCol AS VARCHAR(5))+'.y1 as y'+CAST(@CurCol AS VARCHAR(5))
+', C'+CAST(@CurCol AS VARCHAR(5))+'.z1 as z'+CAST(@CurCol AS VARCHAR(5))
SELECT @TSQLTrailer = @TSQLTrailer+'
LEFT JOIN CTE C'+CAST(@CurCol AS VARCHAR(5))+' ON C'+CAST(@CurCol AS VARCHAR(5))+'.number = C.number AND C'+CAST(@CurCol AS VARCHAR(5))+'.RN = '+CAST(@CurCol AS VARCHAR(5))
SET @CurCol = @CurCol+1
END
-- Combine the header and trailer, producing a finished script
SELECT @TSQLHeader = @TSQLHeader + @TSQLTrailer+'
WHERE C.RN=1'
EXEC sp_executesql @TSQLHeader
但是,当然,如果您在问题中遗漏了任何内容,则必须对这些内容进行彻底更改以适应不同的内容。