SQL:为每个组ID选择前2个日期

时间:2013-09-17 10:52:12

标签: sql date select sql-server-2000

我有一个表格,其中包含以下条目,并且在涉及日期时我正在努力进行分组。

  id    ref    startDate     
 ----  ----- -------------  
   1    001     01-01-2013       
   2    001     03-02-2013       
   3    002     31-01-2013       
   4    002     15-01-2013       
   5    001     05-06-2013 ....      

我要做的是为每个参考选择前2个最大日期,以便我得到以下内容。

  id    ref    startDate     
 ----  ----- -------------  
   5    001     05-06-2013   
   2    001     03-02-2013       
   3    002     31-01-2013       
   4    002     15-01-2013  

我认为这意味着要遵循......

SELECT *
FROM   TABLE a
JOIN   (SELECT startDate
        FROM   TABLE b
        JOIN   TABLE c
        ON     b.ref = c.ref AND b.startDate >= c.startDate
        GROUP BY ref) AS d
ON     a.ref = b.ref

我使用SQL 2000,所以不幸的是,分区是不可能的。

4 个答案:

答案 0 :(得分:1)

只需放置此子句(根据您的需要进行修改)在查询的某处,它应该只为您提供特定参考的前两个StartDate。

WHERE b.StartDate IN 

(SELECT TOP 2 StartDate FROM b WHERE a.ref = b.ref ORDER BY StartDate DESC)

由于您的JOIN似乎是您最初尝试过滤的内容,请将您拥有的JOIN替换为上面的WHERE。确保您对其进行编辑,使其与您的实际表名相匹配

答案 1 :(得分:0)

以下是使用相关子查询的方法:

SELECT *
FROM TABLE t
WHERE (select count(*)
       from Table t2
       where t2.ref = t.ref and
             t2.date >= t.date
      ) <= 2;

这假定日期在每个组中都是唯一的。

Here是一个SQL小提琴,显示它正常工作。

编辑:

如果日期不是唯一的,那么可以修改这个以获得前两个日期的顶行:

SELECT *
FROM TABLE t
WHERE (select count(distinct t2.date)
       from Table t2
       where t2.ref = t.ref and
             t2.date >= t.date
      ) <= 2;

或者,它可以通过这种方式限制为两行:

SELECT *
FROM TABLE t
WHERE (select count(*)
       from Table t2
       where t2.ref = t.ref and
             (t2.date > t.date or t2.date = t.date and t2.id <= t.id)
      ) <= 2;

答案 2 :(得分:0)

请检查

DECLARE @REF_TABLE AS TABLE(ID INT IDENTITY(1,1),REF VARCHAR(10))
DECLARE @LOOP_COUNT INT
DECLARE @ID INT=1
DECLARE @REF VARCHAR(10)
SELECT @LOOP_COUNT=COUNT(*) FROM @REF_TABLE
SELECT * INTO #TEMP FROM YOURTABLE WHERE 1=2
INSERT INTO @REF_TABLE SELECT DISTINCT REF FROM YOURTABLE
WHILE @LOOP_COUNT<@ID
BEGIN
SELECT @REF=REF FROM @REF_TABLE WHERE ID=@ID
INSERT INTO #TEMP SELECT TOP 2 * FROM YOURTABLE WHERE REF=@REF ORDER BY startDate DESC
SELECT @ID=@ID+1

END

SELECT * FROM #TEMP`

答案 3 :(得分:0)

我认为这可以满足您的需求(我知道它有点长,因为我们不能使用CTE或任何Windows功能)。

出于测试目的,我添加了一些额外的记录(same ref with duplicate startdatedifferent refs with same startdate),并进行了评论。

<强> Sql fiddle is here

select min(id) id, t.ref, t.sdate
from t join (
     select ref, max(sdate) as sdate
     from t
     group by ref

     union

     select t.ref, max(t.sdate) as sdate
     from t join (
         select ref, max(sdate) as sdate
         from t
         group by ref
     ) t2 on t.ref = t2.ref and t.sdate < t2.sdate
     group by t.ref 
  ) x on t.ref = x.ref and t.sdate = x.sdate
group by t.ref, t.sdate 
order by t.ref, t.sdate desc