SQL查询仅检索每个id的一个匹配项

时间:2012-01-27 09:21:25

标签: sql field

这是我的(简化)表格:

id     eventName       seriesKey    eventStart
1      Event1          5000         2012-01-01 14:00:00
2      Event2          5001         2012-01-01 14:30:00
3      Event3          5000         2012-01-01 14:50:00
4      Event4          5002         2012-01-01 14:55:00
5      Event5          5001         2012-01-01 15:00:00
6      Event6          5002         2012-01-01 15:30:00
7      Event7          5002         2012-01-01 16:00:00 

我必须构建一个按eventStart (ASC)对表格进行排序的查询,但对于每个seriesKey,我只需要出现一次。

非常感谢

3 个答案:

答案 0 :(得分:4)

尝试使用GROUP BY进行聚合并使用MIN()等聚合函数。

SELECT seriesKey,
       MIN(eventStart) eventStart
FROM   events
GROUP  BY seriesKey;

这导致:

5000    2012-01-01 14:00:00.000
5001    2012-01-01 14:30:00.000
5002    2012-01-01 14:30:00.000

如果您对事件表中的所有列感兴趣,而不仅仅是我选择的上述两列,那么在某些数据库(例如SQL Server)中有一个奇怪的实现可能会对您有所帮助:

SELECT *
FROM   events e1
WHERE  e1.ID IN
(
       SELECT   TOP 1 e2.ID
       FROM     events e2
       WHERE    e2.seriesKey = e1.seriesKey
       ORDER BY e2.eventStart
);

导致:

1   Event1  5000    2012-01-01 14:00:00.000
2   Event2  5001    2012-01-01 14:30:00.000
6   Event2  5002    2012-01-01 14:30:00.000

答案 1 :(得分:2)

如果您还需要与该键关联的其他列,则有两个选项:

select *
from (
  select id, 
         eventName, 
         seriesKey,
         eventStart,
         row_number() over (partition by seriesKey order by eventStart) as rn
  from the_event_table
) t
where rn = 1
order by eventStart

或不支持窗口函数的旧DBMS:

  select t1.id, 
         t1.eventName, 
         t1.seriesKey,
         t1.eventStart
  from the_event_table t1
  where t1.eventStart = (select min(t2.eventStart)
                         from the_event_table t2
                         where t2.seriesKey = t1.seriesKey)
  order by eventStart

答案 2 :(得分:0)

你可以获得每个seriesKey的更早日期:

select * from 
(
select seriesKey, min(eventStart) as mindate
group by seriesKey
)
order by mindate