2012-04-02 28 views
11

Tôi có một số bảng như thế nàyNhóm bởi các giá trị có trong chuỗi

row chequeNo 
1  15 
2  19 
3  20 
4  35 
5  16 

và tôi cần để có được kết quả như thế này

row from to  
1 15 16  
2 19 20  
3 35 35 

vì vậy tôi cần nhóm chequeNo nơi các giá trị sẽ được tuần tự mà không bị gián đoạn. chequeNo là cột duy nhất. Ngoài ra nó nên được thực hiện với một truy vấn chọn sql, bởi vì tôi không có quyền tạo bất kỳ cấu trúc sql nào ngoại trừ các truy vấn chọn.

Vì vậy, điều đó có khả thi không?

sẽ được biết ơn sự giúp đỡ nào

+7

Và cơ sở dữ liệu bạn sử dụng là gì? – Thilo

+4

Hoặc ví dụ của bạn không có ý nghĩa hoặc tôi thiếu một cái gì đó –

+1

Bạn có chắc chắn rằng kết quả mong muốn mà bạn đã viết ở trên là chính xác không? Tôi không thấy mẫu nào trong đó. –

Trả lời

2

này nên làm việc với Oracle 10 (chỉ thử nghiệm với Oracle 11)

select group_nr + 1, 
     min(chequeno) as start_value, 
     max(chequeno) as end_value 
from (
    select chequeno, 
     sum(group_change_flag) over (order by rn) as group_nr 
    from (
    select row_number() over (order by chequeno) as rn, 
      chequeno, 
      case 
      when chequeno - lag(chequeno,1,chequeno) over (order by chequeno) <= 1 then 0 
      else 1 
      end as group_change_flag 
    from foo 
) t1 
) t2 
group by group_nr 
order by group_nr 

(nó sẽ làm việc với bất kỳ DBMS hỗ trợ chức năng cửa sổ tiêu chuẩn SQL, ví dụ như PostgreSQL, DB2, SQL server 2012)

21

Bạn có thể sử dụng kỹ thuật Aketi Jyuuzou được gọi là Tabibitosan đây:

SQL> create table mytable (id,chequeno) 
    2 as 
    3 select 1, 15 from dual union all 
    4 select 2, 19 from dual union all 
    5 select 3, 20 from dual union all 
    6 select 4, 35 from dual union all 
    7 select 5, 16 from dual 
    8/

Table created. 

SQL> with tabibitosan as 
    2 (select chequeno 
    3   , chequeno - row_number() over (order by chequeno) grp 
    4  from mytable 
    5 ) 
    6 select row_number() over (order by grp) "row" 
    7  , min(chequeno) "from" 
    8  , max(chequeno) "to" 
    9 from tabibitosan 
10 group by grp 
11/

     row  from   to 
---------- ---------- ---------- 
     1   15   16 
     2   19   20 
     3   35   35 

3 rows selected. 

Trân trọng,
Rob.

+0

Rất hay. Thanh lịch hơn nhiều so với giải pháp của tôi. –

+2

+1 cảm ơn đã đặt tên cho kỹ thuật, một chút thông tin bổ sung sẽ biến đổi "đây là câu trả lời của bạn 1308044" thành "đây là một kỹ thuật chung mà bạn nên biết". –

+0

cảm ơn rất nhiều. Tôi đã tích hợp giải pháp này vào truy vấn thực và giờ nó hoạt động tốt. – Harrison

0

Đây là một "vani đồng bằng" cách tiếp cận:

SELECT T1.chequeNo, T2.chequeNo 
FROM Table1 AS T1 INNER JOIN Table1 AS T2 ON T2.chequeNo >= T1.chequeNo 
WHERE 
NOT EXISTS (SELECT T0.chequeNo FROM Table1 T0 WHERE T0.chequeNo IN ((T1.chequeNo-1), (T2.chequeNo+1))) 
AND (SELECT COUNT(*) FROM Table1 T0 WHERE T0.chequeNo BETWEEN T1.chequeNo AND T2.chequeNo)=(T2.chequeNo - T1.chequeNo + 1) 
ORDER BY 1,2 

Xin vui lòng cho tôi biết nếu nó quá kém hiệu quả đối với các tập dữ liệu lớn.

0
CREATE TABLE YOUR_TABLE (
    chequeNo NUMBER PRIMARY KEY 
); 

INSERT INTO YOUR_TABLE VALUES (15); 
INSERT INTO YOUR_TABLE VALUES (19); 
INSERT INTO YOUR_TABLE VALUES (20); 
INSERT INTO YOUR_TABLE VALUES (35); 
INSERT INTO YOUR_TABLE VALUES (16); 

SELECT T1.chequeNo "from", T2.chequeNo "to" 
FROM 
    (
     SELECT chequeNo, ROW_NUMBER() OVER (ORDER BY chequeNo) RN 
     FROM (
      SELECT chequeNo, LAG(chequeNo) OVER (ORDER BY chequeNo) PREV 
      FROM YOUR_TABLE 
     ) 
     WHERE PREV IS NULL OR chequeNo > PREV + 1 
    ) T1 
    JOIN 
    (
     SELECT chequeNo, ROW_NUMBER() OVER (ORDER BY chequeNo) RN 
     FROM (
      SELECT chequeNo, LEAD(chequeNo) OVER (ORDER BY chequeNo) NEXT 
      FROM YOUR_TABLE 
     ) 
     WHERE NEXT IS NULL OR chequeNo < NEXT - 1 
    ) T2 
    USING (RN); 

Kết quả:

from     to      
---------------------- ---------------------- 
15      16      
19      20      
35      35      

Nếu chúng ta gia vị mọi thứ lên một chút ...

INSERT INTO YOUR_TABLE VALUES (17); 
INSERT INTO YOUR_TABLE VALUES (18); 

... chúng tôi nhận được:

from     to      
---------------------- ---------------------- 
15      20      
35      35      
Các vấn đề liên quan