我有一个非常简单的表(用于演示)
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的两个“最低”日期值放入一行,如果该ID只有一个日期,则使用null值。上面的查询有效,但是必须有一种更好/更清洁的方式来实现,而我只是没有看到。如果这很重要,我正在使用SQL Server 2008。
最佳答案
您可以使用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
关于sql - 我可以改善这个查询吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15931293/