2013-04-10 10 views
6

私は非常に単純な(デモ用)テーブルこのクエリを改善することはできますか?

CREATE TABLE t1 (id int,d1 date); 

と、このクエリを持っています。

SELECT 
    A.id, 
    minA, 
    minB 
FROM (SELECT id, MIN(d1) AS minA 
    FROM t1 
    GROUP BY id) AS A 
    LEFT JOIN (SELECT C.id, MIN(C.d1) AS minB 
     FROM t1 AS C 
     INNER JOIN (SELECT id, MIN(d1) AS minD 
      FROM t1 
      GROUP BY id) AS D ON C.id = D.id AND C.d1 > D.minD 
     GROUP BY C.id) AS B ON A.id = B.id 

SQL Fiddle link here

IDのための唯一の1日があった場合、基本的に私は、NULL値で、列に各IDには2つの「最低」の日付値を取得しようとしています。上記のクエリは機能しますが、私が見ていないより良い/よりクリーンな方法が必要です。私はSQL Server 2008を使用しています。

答えて

18

次の2つの最古の日付を取得するためにrow_number()を使用して、CASEで、集計関数を使用して列にデータをピボットすることができます

select id, 
    max(case when rn = 1 then d1 end) MinA, 
    max(case when rn = 2 then d1 end) MinB 
from 
(
    select id, 
    d1, 
    row_number() over(partition by id order by d1) rn 
    from t1 
) src 
where rn < 3 
group by id; 

SQL Fiddle with Demoを参照してください。

それとも、列に日付の行をオンにするPIVOT機能を使用することができます。

select id, 
    [1] MinA, 
    [2] MinB 
from 
(
    select id, 
    d1, 
    row_number() over(partition by id order by d1) rn 
    from t1 
) src 
pivot 
(
    max(d1) 
    for rn in ([1], [2]) 
) piv; 

SQL Fiddle with Demo

+0

を参照してください、私は非常によく似た何かをやってみましたが、何らかの理由で私のピボットは私が2で終わるさせ各IDの行行1はIDと最初の日付(2番目の日付はNULL)を持ち、2行目はIDと2番目の日付(最初の列はnull)を持ちます。しかし、このソリューションをありがとう! – Crag

+0

@Cragあなたは喜んで、うまくいきました。 – Taryn

+4

@ YatinSaraiya:あなたのポイントを守ることができない場合は、あまり意味がありません。 – Ryan

関連する問題