不幸的是,我必须为外部应用程序提供3列格式的查询结果。
示例:
DECLARE @tmp TABLE ( id INT
, somevalue VARCHAR(30) )
INSERT @tmp
VALUES ( 1, 'Text1' )
, ( 2, 'Text2' )
, ( 3, 'Text3' )
, ( 4, 'Text4' )
, ( 5, 'Text5' )
, ( 6, 'Text6' )
, ( 7, 'Text7' )
, ( 8, 'Text8' )
, (12, 'Text12')
, (13, 'Text13')
SELECT *
FROM @tmp
但我需要这样的结果集:
|ID1 |SOMEVALUE1|ID2 |SOMEVALUE2|ID3 |SOMEVALUE3|
|1 |Text1 |2 |Text2 |3 |Text3 |
|4 |Text4 |5 |Text5 |6 |Text6 |
|7 |Text7 |8 |Text8 |12 |Text12 |
|13 |Text13 |null|null |null|null |
以这种方式从平面表格式化结果集的最佳方法是什么?
答案 0 :(得分:3)
通过这种方式,您可以在3列上传播值
WITH
r as (
select *, ROW_NUMBER() over (order by id) n
from tmp
)
SELECT T1.ID ID1, T1.SOMEVALUE SOMEVALUE1, T2.ID ID2, T2.SOMEVALUE SOMEVALUE2, T3.ID ID3, T3.SOMEVALUE SOMEVALUE3
FROM r T1
LEFT JOIN r t2 ON (T2.n = T1.n+1)
LEFT JOIN r t3 ON (T3.n = t2.n+1)
WHERE (T1.n % 3) = 1
ORDER BY T1.id
答案 1 :(得分:2)
首先使用您的表设置一个cte,然后使用row_number列设置您的id列中的空白。我按照id排序,因为我认为这是你想要的顺序。
然后,加入该cte 3次,每个列组需要一个。第一列将有row_numbers 1,4,7等 - 基本上每个3的倍数加一。可以找到其他列,因为它们之后是一行和两行。
with cte as (
SELECT ROW_NUMBER() over (order by id) as rowno, *
FROM @tmp
)
select a.id ID1, a.somevalue SOMEVALUE1, b.id ID2, b.somevalue SOMEVALUE2, c.id ID3, c.somevalue SOMEVALUE3
from cte a
left join cte b on b.rowno = a.rowno + 1
left join cte c on c.rowno = a.rowno + 2
where a.rowno % 3 = 1
如果条目中没有3的完美倍数,则只会在其他列中获得空值。
答案 2 :(得分:0)
DECLARE @tmp TABLE ( id INT
, somevalue VARCHAR(30) )
INSERT @tmp
VALUES ( 1, 'Text1' )
, ( 2, 'Text2' )
, ( 3, 'Text3' )
, ( 4, 'Text4' )
, ( 5, 'Text5' )
, ( 6, 'Text6' )
, ( 7, 'Text7' )
, ( 8, 'Text8' )
, ( 9, 'Text9' )
;WITH cte AS(
SELECT *, ROW_NUMBER() OVER (ORDER BY id)%3 rn3
FROM @tmp
),
cteR1 AS(
SELECT c1.id, c1.somevalue, ROW_NUMBER() OVER (ORDER BY c1.id) AS rn
FROM cte c1
WHERE c1.rn3 = 1
),
cteR2 AS(
SELECT c1.id, c1.somevalue, ROW_NUMBER() OVER (ORDER BY c1.id) AS rn
FROM cte c1
WHERE c1.rn3 = 2
),
cteR3 AS(
SELECT c1.id, c1.somevalue, ROW_NUMBER() OVER (ORDER BY c1.id) AS rn
FROM cte c1
WHERE c1.rn3 = 0
)
SELECT R1.id, R1.somevalue, R2.id, R2.somevalue, R3.id, R3.somevalue
FROM cteR1 R1
JOIN cteR2 R2 ON R1.rn = R2.rn
JOIN cteR3 R3 ON R1.rn = R3.rn