从表中只获取第一个和最后一个匹配项

时间:2014-06-17 12:08:39

标签: sql sql-server

我有一张这样的表:

ID action Date
xxx action1 20140101
xxx action2 20140102
yyy action1 20140116
yyy action2 20140117
yyy action3 20140122
yyy action4 20140123
yyy action5 20140131
zzz action1 20140103
zzz action2 20140106
zzz action3 20140107

有没有办法为每个ID(第一个和最后一个)选择2条记录

xxx action1 20140101
xxx action2 20140102
yyy action1 20140116
yyy action5 20140131
zzz action1 20140103
zzz action3 20140107

或者做一些其他的阐述

ID firstAction Date LastAction Date
xxx action1 20140101 action2 20140102
yyy action1 20140116 action5 20140131
zzz action1 20140103 action3 20140107

使用JAVA或C ++编码可以轻松达到这些结果。用SQL? 首先,我按ID排序,然后按日期排序,但后来我不知道如何继续

3 个答案:

答案 0 :(得分:1)

您可以使用窗口函数执行此操作:

select t.id, t.action, t.date
from (select t.*,
             row_number() over (partition by id order by date asc) as seqnum_asc,
             row_number() over (partition by id order by date desc) as seqnum_desc
      from table t
     ) t
where seqnum_asc = 1 or seqnum_desc = 1;

答案 1 :(得分:1)

您可以使用MIN和MAX聚合函数在SQL中执行此操作,如下所示:

SELECT ID, MIN(Date) AS FirstActionDate, MAX(Date) AS LastActionDate 
FROM Table 
GROUP BY ID

答案 2 :(得分:1)

试试这个:

select x.ID, x.mindate as FirstActionDate, x.FirstAction as FirstAction, y.maxdate as LastActionDate, y.LastAction as LastAction
from 
(
  --FirstDate and Action 
  select a.ID, a.mindate as mindate, t.action as FirstAction 
  from 
  (

    select ID, Min(date) as mindate
     from data
     group by ID
   ) a inner join data t on a.mindate = t.date
 ) x inner join 
  (
    --Last Date And Action
    select a.ID, a.maxdate, t.action as LastAction 
    from 
    (

      select ID, max(date) as maxdate
       from data
       group by ID
     ) a inner join data t on a.maxdate = t.date
  ) y on x.ID = y.ID

Demo

编辑:我认为这里的正确方法是: (更新的演示以匹配您的示例数据)

  1. 获取ID和第一个日期(min(date)),然后加入原始表格(a.mindate = t.date)以获取操作名称 - 这将为您提供故事的一半 - 表格{{1 }}
  2. 以类似的方式,您可以构建表x以获取最后的日期和操作
  3. 最后,您将他们加入y列,以获取单ID语句中的所有列。