簡體   English   中英

SQL:選擇每個組ID的前2個日期

[英]SQL: SELECT TOP 2 DATES FOR EACH GROUP ID

我有一張桌子,上面有類似下面的條目,當涉及到日期時,我正在努力進行分組。

  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,因此不幸的是分區是不可能的。

只需將此子句(根據您的需要進行修改)放在查詢中的某個位置,對於特定的引用,它應該只為您提供前兩個StartDate。

WHERE b.StartDate IN 

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

由於您的JOIN似乎是您最初嘗試對其進行過濾的內容,因此將您擁有的JOIN替換為上面的WHERE 確保對其進行編輯,使其與您的實際表名匹配

這是使用相關子查詢的方法:

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

假設每個組中的日期都是唯一的。

是一個SQL Fiddle,顯示了它的工作原理。

編輯:

如果日期不是唯一的,則可以通過以下方式修改日期以獲取前兩個日期的前幾行:

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;

請檢查一下

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`

我認為這滿足了您的需求(我知道這有點長,因為我們不能使用CTE或任何Windows函數)。

為了進行測試,我添加了幾個額外的記錄( same ref with duplicate startdatedifferent refs with same startdate ),並添加了注釋。

SQL小提琴在這里

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM