2012-04-02 128 views
11

我有這樣集團通過值在序列

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

一些表,我需要得到這樣

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

的結果,所以我需要的chequeNo組,其中值將是連續的沒有任何中斷。 chequeNo是獨一無二的專欄。此外,它應該用一個sql select查詢來完成,因爲我沒有權限創建除select查詢以外的任何sql結構。

那麼有可能嗎?

將不勝感激任何幫助

+7

和數據庫你使用是? – Thilo 2012-04-02 13:29:50

+4

您的示例沒有任何意義,或者我錯過了某些東西 – 2012-04-02 13:30:33

+1

您確定您上面寫的所需結果是正確的嗎?我看不到它的模式。 – 2012-04-02 13:31:11

回答

2

這應該與Oracle 10工作(只支持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 

(它應該支持標準的SQL窗口功能的任何數據庫管理系統,如PostgreSQL的工作, DB2,SQL Server 2012中)

21

您可以使用阿凱蒂Jyuuzou的技術稱爲Tabibitosan這裏:

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. 

Regards,
Rob。

+0

非常酷。比我的解決方案更優雅。 – 2012-04-02 14:05:23

+2

+1感謝這項技術的名稱,那麼額外信息的一小部分將「您的答案1308044」轉換爲「您應該知道的一般技術。」 – 2012-04-02 14:53:41

+0

非常感謝。我已經將這個解決方案集成到真正的查詢中,現在它工作正常。 – Harrison 2012-04-03 08:06:31

0

這裏是一個「普通的香草」的方法:

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 

請讓我知道這是否是大數據集的效率太低。

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); 

結果:

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

如果我們香料的東西一點點...

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

...我們得到:

from     to      
---------------------- ---------------------- 
15      20      
35      35