如何使用Oracle SQL选择第一组连续行

时间:2010-06-24 11:00:49

标签: sql oracle

我有以下数据:

Date             GroupID     Value 
1/01/2000    1                 44 
2/01/2000    1                 55 
3/01/2000    1                 66 
4/01/2000    2                 77 
5/01/2000    2                 88 
6/01/2000    1                 99 
7/01/2000    1                 22 

我正在寻找能够在按日期排序时选择具有连续GroupID的第一组记录的查询。即在这个例子中我会得到:

1/01/2000    1                 44 
2/01/2000    1                 55 
3/01/2000    1                 66 

当下一行中的组ID发生变化时,我不会得到任何后续数据。

非常感谢帮助

由于

埃利

3 个答案:

答案 0 :(得分:9)

一种方法:

SQL> WITH DATA AS (
  2  SELECT '1/01/2000' mydate, 1 GroupID, 44 Value FROM DUAL
  3  UNION ALL SELECT '2/01/2000', 1, 55 FROM DUAL
  4  UNION ALL SELECT '3/01/2000', 1, 66 FROM DUAL
  5  UNION ALL SELECT '4/01/2000', 2, 77 FROM DUAL
  6  UNION ALL SELECT '5/01/2000', 2, 88 FROM DUAL
  7  UNION ALL SELECT '6/01/2000', 1, 99 FROM DUAL
  8  UNION ALL SELECT '7/01/2000', 1, 22 FROM DUAL
  9  )
 10  SELECT mydate, groupid, VALUE
 11    FROM (SELECT mydate, groupid, VALUE,
 12                 SUM(gap) over(ORDER BY mydate) contiguous_group
 13             FROM (SELECT mydate, groupid, VALUE,
 14                           CASE
 15                              WHEN lag(groupid)
 16                                   over(ORDER BY mydate) != groupid
 17                              THEN
 18                               1
 19                              ELSE
 20                               0
 21                           END gap
 22                      FROM DATA))
 23   WHERE contiguous_group = 0;

MYDATE       GROUPID      VALUE
--------- ---------- ----------
1/01/2000          1         44
2/01/2000          1         55
3/01/2000          1         66

答案 1 :(得分:0)

这是另一种方法

    WITH data AS
 (SELECT '1/01/2000' mydate,
         1 groupid,
         44 VALUE
    FROM dual
  UNION ALL
  SELECT '2/01/2000',
         1,
         55
    FROM dual
  UNION ALL
  SELECT '3/01/2000',
         1,
         66
    FROM dual
  UNION ALL
  SELECT '4/01/2000',
         2,
         77
    FROM dual
  UNION ALL
  SELECT '5/01/2000',
         2,
         88
    FROM dual
  UNION ALL
  SELECT '6/01/2000',
         1,
         99
    FROM dual
  UNION ALL
  SELECT '7/01/2000',
         1,
         22
    FROM dual)
SELECT *
  FROM data
 WHERE rownum <= (SELECT MAX(rwn)
                    FROM (SELECT COUNT(*) over(PARTITION BY groupid ORDER BY rownum) cnt,
                                 rownum rwn
                            FROM data)
                   WHERE rwn = cnt);

P.S。如果所有mydate值都相同,那么来自Vincent的查询将无效

答案 2 :(得分:0)

虽然已经回答,但想分享一下。它使用JOINs代替

WITH DATA AS (
SELECT '1/01/2000' mydate, 1 GroupID, 44 v
UNION ALL SELECT '2/01/2000', 1, 55 
UNION ALL SELECT '3/01/2000', 1, 66 
UNION ALL SELECT '4/01/2000', 2, 77 
UNION ALL SELECT '5/01/2000', 2, 88 
UNION ALL SELECT '6/01/2000', 1, 99 
UNION ALL SELECT '7/01/2000', 1, 22 
) 

SELECT 
  a.GroupID,
  a.mydate
FROM 
  DATA a 
  JOIN DATA b ON ( b.mydate <= a.mydate )
GROUP BY 
  a.GroupID,
  a.mydate
HAVING 
  MAX( b.GroupID ) = MIN ( b.GroupID )
ORDER BY 
  a.mydate