2012-04-02 4 views
11

ich eine Tabelle haben wie dieseGruppe von Werten, die in der Folge sind

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

und ich brauche das Ergebnis wie dieses

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

zu bekommen, damit ich Gruppen von chequeNo müssen, wo Werte sequentiell sein würde ohne Unterbrechungen. chequeNo ist eine eindeutige Spalte. Zusätzlich sollte es mit einer SQL SELECT-Abfrage durchgeführt werden, da ich keine Berechtigungen zum Erstellen von SQL-Strukturen außer SELECT-Abfragen habe.

So ist es möglich?

Wäre für jede Hilfe

+7

Und die Datenbank Sie sind Verwenden ist? – Thilo

+4

Entweder ist Ihr Beispiel nicht sinnvoll oder mir fehlt etwas –

+1

Sind Sie sicher, dass das gewünschte Ergebnis, das Sie oben geschrieben haben, korrekt ist? Ich sehe kein Muster darin. –

Antwort

2

Dies sollte funktionieren mit Oracle 10 (nur getestet mit 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 

dankbar sein (es mit allen DBMS unterstützt Standard-SQL-Windowing-Funktionen funktionieren sollte, zB PostgreSQL, DB2, SQL Server 2012)

21

Sie können Aketi Jyuuzou sprühte Tabibitosan hier genannt verwenden:

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. 

Grüße,
Rob. Hier

+0

Sehr cool. Viel eleganter als meine Lösung. –

+2

+1 danke geben den Namen der Technik, das kleine bisschen Extra-Info verwandelt "hier ist Ihre Antwort 1308044" zu "Hier ist eine allgemeine Technik, die Sie wissen sollten." –

+0

vielen Dank. Ich habe diese Lösung in echte Abfrage integriert und jetzt funktioniert es gut. – Harrison

0

ist ein „plain vanilla“ Ansatz:

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 

Bitte lassen Sie mich wissen, ob es für große Datenmengen zu ineffizient ist.

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

Ergebnis:

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

Wenn wir die Dinge ein wenig aufzupeppen ...

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

... erhalten wir:

from     to      
---------------------- ---------------------- 
15      20      
35      35      
Verwandte Themen