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 链接在这里

基本上,我试图将每个 ID 的两个“最低”日期值排成一行,如果 ID 只有一个日期,则为空值。上面的查询有效,但必须有一种更好/更清洁的方法来做到这一点,而我只是没有看到。如果这很重要,我正在使用 SQL Server 2008。

4

1 回答 1

18

您可以使用row_number()来获取两个最旧的日期,然后使用带有 a 的聚合函数将数据转换为列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

于 2013-04-10T16:27:05.637 回答