2017-09-28 10 views
-1

不幸にも、外部アプリケーション用に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  | 

そのように平らなテーブルからの結果セットをフォーマットするための最良の方法は何ですか?このようにして

+2

誰かが(10、 'Text10')を挿入した後に期待される結果はありますか? idギャップについてはどうですか? – jarlh

+0

私はそれがtsqlでやるのはばかげていることを知っています。しかし私の手はここに縛られている。空の列はnullで埋められます。 IDはどこに結果を配置するかは関係ありません。 –

+0

'999、 'Text999''を追加して予期した結果を更新してください – MtwStark

答えて

3

あなたはまず、あなたのテーブルを使用して、CTEを設定し、あなたのid列のギャップを持っている場合、ROW_NUMBER列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 
2

に値を分散します。私はあなたが望む順序であると仮定したので、私はIDによって命令しました。

次に、必要な列グループごとに1回、そのcteに3回参加します。最初の列にはrow_numbers 1,4,7などがあります。基本的に3の倍数に1を加えたものです。それ以降は1行と2行であるため、他の列を見つけることができます。

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の倍数がない場合は、追加の列にnullが追加されます。

+0

IDに隙間がある場合(ジョインが壊れます)、私の答えを見てください。それは似ていますが、row_number – MtwStark

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 
関連する問題