2009-09-18 5 views
1

J'ai une table avec la colonne suivante.Récupérer des données dans le groupe en fonction de la valeur de l'autre colonne

BoxNumber   Status 
580     4 
581     4 
582     4 
583     4 
584     2 
585     2 
586     4 
587     4 
588     4 
589     4 
590     2 
591     2 

J'ai besoin d'une requête de sélection pour obtenir la sortie suivante.

StartingBoxNumber EndingBoxNumber Status 
580      583   4 
584      585   2 
586      589   4 
590      591   2 
+0

S'il vous plaît le rendre plus clair. Formatez également les données de la source de la table à aligner correctement. Votre question est difficile à lire. Que devrait contenir le champ "status" dans le jeu d'enregistrements résultant? –

+0

J'ai reformaté les données pour les rendre lisibles. Je peux voir ce qui est nécessaire, je pense, mais je ne l'ai pas résolu en SQL: commence par le plus bas BoxNumber (580), qui a le statut 4. Maintenant, parcourez les numéros de la boîte dans l'ordre croissant jusqu'à ce que vous atteignez 4 (584). Vous avez maintenant votre premier résultat: 580 au numéro de case immédiatement précédent 584 (583) ont le statut 4. –

+0

La solution implique probablement les fonctions analytiques LEAD() et LAG(). –

Répondre

0

En supposant les numéros de boîte sont toujours consécutifs:

SELECT COALESCE(
     LAG(Boxnumber) OVER (ORDER BY BoxNumber), 
     (
     SELECT MIN(BoxNumber) 
     FROM mytable 
     )) AS StartBoxNumber, 
     BoxNumber AS EndBoxNumber, 
     status 
FROM mytable qo 
WHERE NOT EXISTS 
     (
     SELECT NULL 
     FROM mytable qi 
     WHERE qi.boxnumber = qo.boxnumber + 1 
       AND qi.status = qo.status 
     ) 
1

Vous pouvez obtenir le résultat avec un seul balayage de la table, en utilisant des analyses pour définir les « groupes » de rangées contiguës:

SQL> SELECT MIN(boxnumber), MAX(boxnumber), status 
    2 FROM (SELECT boxnumber, status, 
    3     SUM(status_change) over(ORDER BY boxnumber) group_id 
    4    FROM (SELECT boxnumber, status, 
    5       CASE 
    6        WHEN lag(status) over(ORDER BY boxnumber) 
    7         = status 
    8        AND lag(boxnumber) over(ORDER BY boxnumber) 
    9         = boxnumber - 1 THEN 
10        0 
11        ELSE 
12        1 
13       END status_change 
14      FROM box)) 
15 GROUP BY status, group_id 
16 ORDER BY 1; 

MIN(BOXNUMBER) MAX(BOXNUMBER)  STATUS 
-------------- -------------- ---------- 
      580   583   4 
      584   585   2 
      586   589   4 
      590   591   2 
Questions connexes