2017-09-25 12 views
2

Par exemple, avec l'aide des tableaux ci-dessous,Au Comte l'occurrence de modèle entre les valeurs spécifiques dans le tableau Oracle

Rn ID Pattern 
1 C20 
2 C21 
3 C25 
4 C25 
5 C25 
6 C25 
7 C25 
8 C21 
9 C23 
10 C20 
11 C21 
12 C25 
13 C25 
14 C25 
15 C22 
16 C21 
17 C20 

Je veux compter le modèle C25 entre chaque C20.

Le résultat devrait être,

-> Nombre de C25 b/n 1ère et 2ème apparition de C20 = 5
voir ci-dessous référence

Rn ID Pattern 
1 C20 
2 C21 
3 C25 
4 C25 
5 C25 
6 C25 
7 C25 
8 C21 
9 C23 
10 C20 

-> Nombre de C25 b/n 2ème et 3ème apparition de C20 = 3

10 C20 
11 C21 
12 C25 
13 C25 
14 C25 
15 C22 
16 C21 
17 C20 

T Rings à l'avance.

+0

Quelle est la version de base de données Oracle? Ou voulez-vous vraiment dire '[mysql]'? Soyez prudent avec le marquage de la base de données: les réponses requièrent souvent une syntaxe spécifique à un produit de base de données particulier, ce qui est susceptible d'être le cas ici. – APC

Répondre

1

Utilisez la LAG fonction analytique avec l'option IGNORE NULLS pour trouver la ligne précédente au début de votre gamme puis utilisez la fonction analytique COUNT avec une fenêtre de plage pour obtenir le nombre:

SQL Fiddle

Oracle 11g R2 Configuration du schéma:

CREATE TABLE table_name (rn, id) AS 
    SELECT 1, 'C20' FROM DUAL UNION ALL 
    SELECT 2, 'C21' FROM DUAL UNION ALL 
    SELECT 3, 'C25' FROM DUAL UNION ALL 
    SELECT 4, 'C25' FROM DUAL UNION ALL 
    SELECT 5, 'C25' FROM DUAL UNION ALL 
    SELECT 6, 'C25' FROM DUAL UNION ALL 
    SELECT 7, 'C25' FROM DUAL UNION ALL 
    SELECT 8, 'C21' FROM DUAL UNION ALL 
    SELECT 9, 'C23' FROM DUAL UNION ALL 
    SELECT 10, 'C20' FROM DUAL UNION ALL 
    SELECT 11, 'C21' FROM DUAL UNION ALL 
    SELECT 12, 'C25' FROM DUAL UNION ALL 
    SELECT 13, 'C25' FROM DUAL UNION ALL 
    SELECT 14, 'C25' FROM DUAL UNION ALL 
    SELECT 15, 'C22' FROM DUAL UNION ALL 
    SELECT 16, 'C21' FROM DUAL UNION ALL 
    SELECT 17, 'C20' FROM DUAL; 

Query 1:

SELECT * 
FROM (
    SELECT t.*, 
     COUNT(CASE id WHEN 'C25' THEN 1 END) 
      OVER (ORDER BY rn 
        ROWS BETWEEN (rn - prev_rn) PRECEDING AND CURRENT ROW) 
      AS num_c25 
    FROM (
    SELECT t.*, 
      LAG(CASE id WHEN 'C20' THEN rn END, 1, 1) 
      IGNORE NULLS OVER (ORDER BY rn) AS prev_rn 
    FROM table_name t 
) t 
) 
WHERE id = 'C20' 

Results:

| RN | ID | PREV_RN | NUM_C25 | 
|----|-----|---------|---------| 
| 1 | C20 |  1 |  0 | 
| 10 | C20 |  1 |  5 | 
| 17 | C20 |  10 |  3 | 

Une autre façon est d'utiliser une requête hiérarchique:

Requête 2:

SELECT * 
FROM (
    SELECT t.*, 
     COUNT(CASE id WHEN 'C25' THEN 1 END) OVER (ORDER BY rn ROWS BETWEEN LEVEL - 1 PRECEDING AND CURRENT ROW) AS num_c25, 
     CONNECT_BY_ROOT rn AS start_rn, 
     CONNECT_BY_ISLEAF AS isleaf 
    FROM table_name t 
    START WITH id = 'C20' 
    CONNECT BY PRIOR rn + 1 = rn 
    AND id <> 'C20' 
) 
WHERE isleaf = 1 

Results:

| RN | ID | NUM_C25 | START_RN | ISLEAF | 
|----|-----|---------|----------|--------| 
| 9 | C23 |  5 |  1 |  1 | 
| 16 | C21 |  3 |  10 |  1 | 
| 17 | C20 |  0 |  17 |  1 |