2010-06-24 36 views
8

tôi có các dữ liệu sau:Làm thế nào để chọn nhóm liên tục đầu tiên của hàng sử dụng Oracle SQL

 
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 

Tôi đang tìm kiếm một truy vấn có khả năng lựa chọn các nhóm đầu tiên của hồ sơ với một GROUPID liên tục khi tôi đặt hàng bởi Ngày. tức là trong ví dụ này, tôi sẽ nhận được:

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

Vì ID nhóm đã thay đổi trong hàng tiếp theo, tôi sẽ không nhận được bất kỳ dữ liệu nào sau đó.

Trợ giúp sẽ được đánh giá rất

Cảm ơn

Elie

+2

Có đảm bảo chính xác là một bản ghi cho mỗi ngày không? –

Trả lời

9

một cách để làm điều đó:

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 
+0

Cảm ơn bạn vì điều đó, rất hữu ích – Elie

0

Đây là một cách làm thế nào để làm điều đó

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. truy vấn từ Vincent sẽ không hoạt động nếu tất cả các giá trị mydate sẽ giống nhau

+0

Cảm ơn bạn vì điều đó, rất hữu ích – Elie

0

Mặc dù đã được trả lời, muốn chia sẻ nó. Nó sử dụng JOINs thay vì

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 
Các vấn đề liên quan