IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

Suppression ligne n si n-1 n'existe pas


Sujet :

SQL Oracle

  1. #21
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    J'ai une solution, mais j'ai besoin de l'affiner.
    Que faire dans ces cas là :

    Cas1
    Tab1 : {4, 5, 8, 9}
    Tab2 : {1, 2, 3, 7}
    Cas2
    Tab1 : {4, 5, 7, 8}
    Tab2 : {1, 2, 3, 6}
    Cas3
    Tab1 : {4, 5, 8, 9}
    Tab2 : {1, 2, 3, 6}

  2. #22
    Membre habitué Avatar de hammag
    Profil pro
    Inscrit en
    Février 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 511
    Points : 145
    Points
    145
    Par défaut
    Citation Envoyé par Waldar Voir le message
    J'ai une solution, mais j'ai besoin de l'affiner.
    Que faire dans ces cas là :

    Cas1
    Tab1 : {4, 5, 8, 9}
    Tab2 : {1, 2, 3, 7}
    Cas2
    Tab1 : {4, 5, 7, 8}
    Tab2 : {1, 2, 3, 6}
    Cas3
    Tab1 : {4, 5, 8, 9}
    Tab2 : {1, 2, 3, 6}
    Bonjour Waldar,
    d'abord merci pour tes réponses, ensuite pour tes cas:
    cas1 : normalement dans mon cas on aura jamais ce cas, parce que ma table tab2 contient toujours des lignes triée séquentiellement, donc dans tab2 j'aurais 1,2,3 (le 7 n'a pas sa place dans tab2)
    En revanche dans tab1, il est possible d'avoir des séquences avec des trous comme dans ton exemple.
    Idem pour les deux autres cas.

    je m'inspire de tes cas pour te présenter les cas ci-dessous:
    Cas1
    Tab1 : {4, 5, 8, 9}
    Tab2 : {1, 2, 3}
    => suppression des 8 et 9

    Cas2
    Tab1 : {4, 5, 7, 8}
    Tab2 : {1, 2, 3}
    suppression des 7 et 8

    Cas3
    Tab1 : {4, 5, 8, 9}
    Tab2 : {1, 2, 3}
    =>suppression de 8 et 9

    j'espère que cette fois j'étais claire dans mes explications.

  3. #23
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Un truc infâme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    WITH tab1 AS (
    SELECT 1 champ1, 1 champ2, 4 seq FROM DUAL
    UNION ALL SELECT 1 champ1, 1 champ2, 5 seq FROM DUAL
    UNION ALL SELECT 1 champ1, 1 champ2, 6 seq FROM DUAL
    UNION ALL SELECT 1 champ1, 1 champ2, 8 seq FROM DUAL
    UNION ALL SELECT 2 champ1, 1 champ2, 6 seq FROM DUAL
    UNION ALL SELECT 2 champ1, 1 champ2, 7 seq FROM DUAL
    UNION ALL SELECT 2 champ1, 1 champ2, 8 seq FROM DUAL
    )
    , tab2 AS (
    SELECT 1 champ1, 1 champ2, 1 seq FROM DUAL
    UNION ALL SELECT 1 champ1, 1 champ2, 2 seq FROM DUAL
    UNION ALL SELECT 1 champ1, 1 champ2, 3 seq FROM DUAL
    UNION ALL SELECT 2 champ1, 1 champ2, 1 seq FROM DUAL
    UNION ALL SELECT 2 champ1, 1 champ2, 2 seq FROM DUAL
    UNION ALL SELECT 2 champ1, 1 champ2, 3 seq FROM DUAL
    )
    SELECT champ1, champ2, seq
    FROM tab1
    WHERE (champ1, champ2, seq) IN (                 
        SELECT champ1, champ2, case when seq >= min(trou * seq) over (partition by champ1, champ2 order by seq) then seq end
        FROM (
            SELECT champ1, champ2, seq, case when coalesce(seq - lag(seq,1) over(partition by champ1, champ2 order by seq), 1) <> 1 THEN 1 END trou 
            FROM (         
                SELECT champ1, champ2, seq
                FROM tab1
                UNION 
                SELECT champ1, champ2, seq
                FROM tab2
                )
        )            
        )
    L'idée est de :
    - faire l'union des deux tables
    - chercher les trous par champ1, champ2 en utilisant lag
    - de chercher quel est le premier avec min (sachant qu'on a mis à null là où il n'y a pas de trou)
    - virer tout ce qui est plus grand qui est au dessus de ce trou au sens large...

    (Mais avec un peu de chance Waldar aura quelque chose de plus joli )

  4. #24
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 247
    Points : 473
    Points
    473
    Billets dans le blog
    1
    Par défaut
    Si
    - il n'y a rien a supprimer dans tab2
    - min(tab1) vaut toujours max(tab2)+1 ,

    il suffit de jouer ma requete sur tab1 (en place du mot TABLE )

    doit on s'interesser au cas :
    tab2 : 1 ,2 ,3
    tab1 : 7 ,8 ,9

    ?
    ou il faudrait donc vider totalement tab1 ?

    EDIT : j'ai relu les messages et ce cas doit vider tab1 donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    DELETE tab1 
    WHERE seq > (SELECT min (seq)
                 FROM tab1 T1
                 WHERE NOT EXISTS (SELECT 1
                                   FROM tab1 T2 
                                   WHERE T2.seq = T1.seq + 1
                                   )
                 )
    OR (select min (seq ) from tab1) > (select max(seq)+1 from tab2)

  5. #25
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    J'ai appliqué la méthode de Tabibitosan.

    Je suis parti comme Pacmann, j'ai recomposé la liste complète des id et ai simplement cherché le premier trou pour sélectionner tout ce qu'il y a derrière.

    Je suppose que la séquence dans Tab2 commence toujours à 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    WITH tab1 AS
    (
    SELECT 4 as seq FROM dual UNION ALL
    SELECT 5        FROM dual UNION ALL
    SELECT 8        FROM dual
    )
      ,  tab2 as
    (
    SELECT 1 as seq FROM dual UNION ALL
    SELECT 2        FROM dual UNION ALL
    SELECT 3        FROM dual
    )
      ,  tabf as
    (
    select seq from tab1
     union
    select seq from tab2
    )
      ,  tabg as
    (
    SELECT seq, 
           seq - row_number() over(order by seq asc) as grp
      FROM tabf
    )
    SELECT * FROM tab1
     WHERE seq in (select seq from tabg where grp > 0);
     
    SEQ
    ---
      8

  6. #26
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    @jean_cri
    Tu n'as pas géré le cas 3 par exemple
    Cas3
    Tab1 : {4, 5, 8, 9}
    Tab2 : {1, 2, 3}
    =>suppression de 8 et 9

  7. #27
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Effectivement Waldar, c'est plus joli en cherchant directement le signe de la différence de rang, bien joué !

    @jean_cri : attention aussi au fait qu'il faut opérer ça pour chaque groupe défini par (champ1, champ2) : ta comparaison min - max doit être corrélée à la requête principale.
    (Pareil pour Waldar... cela dit de son côté il y a juste quelques GROUP BY / PARTITION BY à ajouter)

  8. #28
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 247
    Points : 473
    Points
    473
    Billets dans le blog
    1
    Par défaut
    @McM : ben si , ca marche
    @pacmann : j'ai compris qu'il fallait tout supprimer des la premiere rupture de continuité, c'est pas ca ?

  9. #29
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Tout à fait Jean-Cri, mais la rupture, il faut la chercher pour chaque groupe !
    (Regarde le post de hammag avec les grosses requêtes, il s'embête vachement à corréler sur <champ1, champ2> un peu partout...)

  10. #30
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 247
    Points : 473
    Points
    473
    Billets dans le blog
    1
    Par défaut
    @pacmann : oui en effet, je me suis basé sur les résumés de ses demandes ou il ne parle jamais des autres champs, et je ne serais pas surpris qu'on lui ai un peu forcé la main pour les utiliser

    Le plus simple c'est de le lui demander clairement.

    @hammag :
    Doit on considerer les sequences pour chaque groupe de champs ? ou peut importe le contenu des autres champs et on ne s'interesse qu'a la valeur de seq ?

  11. #31
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Je n'avais même pas percuté qu'il y avait d'autres colonnes.
    Avec le même jeu de données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    WITH tab1 AS
    (
    SELECT 1 as c1, 1 as c2, 4 as seq FROM DUAL UNION ALL
    SELECT 1      , 1      , 5        FROM DUAL UNION ALL
    SELECT 1      , 1      , 6        FROM DUAL UNION ALL
    SELECT 1      , 1      , 8        FROM DUAL UNION ALL
    SELECT 2      , 1      , 6        FROM DUAL UNION ALL
    SELECT 2      , 1      , 7        FROM DUAL UNION ALL
    SELECT 2      , 1      , 8        FROM DUAL
    )
      ,  tab2 AS
    (
    SELECT 1 as c1, 1 as c2, 1 as seq FROM DUAL UNION ALL
    SELECT 1      , 1      , 2        FROM DUAL UNION ALL
    SELECT 1      , 1      , 3        FROM DUAL UNION ALL
    SELECT 2      , 1      , 1        FROM DUAL UNION ALL
    SELECT 2      , 1      , 2        FROM DUAL UNION ALL
    SELECT 2      , 1      , 3        FROM DUAL
    )
      ,  tabf as
    (
    select c1, c2, seq from tab1
     union
    select c1, c2, seq from tab2
    )
      ,  tabg as
    (
    SELECT c1, c2, seq, 
           seq - row_number() over(partition by c1, c2 order by seq asc) as grp
      FROM tabf a
    )
    SELECT * FROM tab1
     WHERE (c1, c2, seq) IN (SELECT c1, c2, seq
                               FROM tabg
                              WHERE grp > 0);
     
    C1 C2 SEQ
    -- -- ---
     1  1   8 
     2  1   6 
     2  1   7 
     2  1   8

  12. #32
    Membre habitué Avatar de hammag
    Profil pro
    Inscrit en
    Février 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 511
    Points : 145
    Points
    145
    Par défaut
    Citation Envoyé par Jean.Cri1 Voir le message
    @hammag :
    Doit on considerer les sequences pour chaque groupe de champs ? ou peut importe le contenu des autres champs et on ne s'interesse qu'a la valeur de seq ?
    bien sur Jean Cri on doit considérer les séquences pour chaque groupe de champ (clés: champ1 et champ2 )

  13. #33
    Membre habitué Avatar de hammag
    Profil pro
    Inscrit en
    Février 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 511
    Points : 145
    Points
    145
    Par défaut
    Merci pour tout le monde, mais j'ai enfin trouvé une solution en utilisant une table temporaire et plusieurs requêtes consécutives.

    J'ai crée une nouvelle table Temp qui a les mêmes clés de TAB1 et deux autres champs Flag1 et Flag2.
    Je copie les lignes de la table TAB1 dans Temp en calculant la valeur des deux champs Flag1 et Flag 2:
    1ère requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    INSERT INTO Temp 
     SELECT champ1
     ,champ2 
     ,seq
     ,CASE WHEN NOT EXISTS (SELECT seq 
                            FROM TAB1 
                            WHERE champ1 = A.champ1 
                            AND champ2 = A.champ2
                            AND seq =A.seq -1 ) THEN 'N' ELSE 'Y' END 
     ,CASE WHEN NOT EXISTS (SELECT seq 
                            FROM TAB2 
                            WHERE champ1 = A.champ1 
                            AND champ2 = A.champ2
                            AND seq =A.seq -1) THEN 'N' ELSE 'Y' END 
    FROM TAB1 A
    Valeurs de Flag 1 et Flag2
    Pour la ligne i, si la ligne i-1 existe dans TAB1 alors Flag1=Y sinon =N
    Pour la ligne i, si la ligne i-1 existe dans TAB2 alors Flag1=Y sinon =N

    une 2ème requête: tous les lignes qui ont la séquence 1 seront copiées dans TAB2 (ligne i-1=0 n'a aucun sens)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    UPDATE Temp 
      SET flag1='Y' 
     WHERE Seq=1
    3ème requête:
    la requête 1 met Flag1=flag2=N pour chaque ligne i si cette ligne n'a pas la ligne i-1 ni dans TAB2, ni dans TAB1, et cette ligne sera supprimée.
    Donc tous les lignes > i doivent être aussi supprimées. Pour cela il faut mettre les deux champs Flag1=Flag2=N.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    UPDATE Temp a 
      SET flag1='N',flag2='N' 
     WHERE seq >( 
     SELECT MIN(seq) 
      FROM temp 
     WHERE flag1='N' 
       AND flag2='N' 
       AND champ1 = A.champ1 
       AND champ2 = A.champ2)
    enfin, une dernière requête pour supprimer tous les lignes dans TAB1 qui corresponds aux ligne dans Temp avec les deux champs Flag1=Flag2=N.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    DELETE 
    FROM TAB1 A 
    WHERE (champ1,champ2,seq) IN ( 
    SELECT champ1
    champ2 
    seq
    FROM temp 
    WHERE champ1 = A.champ1 
    AND champ2 = A.champ2
    AND seq =A.seq 
    AND flag1='N' 
    AND flag2='N')
    voilà, cette solution répond à mes besoin.

    chao

  14. #34
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    J'ai l'impression d'avoir répondu dans le vide en fait.

  15. #35
    Membre habitué Avatar de hammag
    Profil pro
    Inscrit en
    Février 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 511
    Points : 145
    Points
    145
    Par défaut
    non waldar, tu n'a pas répondu dans le vide, ta requête répond parfaitement à mes besoins et je te remercie beaucoup
    sauf que moi, j'avais appliqué ma solution avant la réception de ton dernier post.

  16. #36
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    L'important c'est que votre problème soit résolu !

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 8
    Dernier message: 05/07/2012, 14h35
  2. [BATCH] Suppression Ligne
    Par kilian dans le forum Windows
    Réponses: 2
    Dernier message: 24/05/2006, 14h02
  3. [VBA][EXCEL] pb suppression ligne
    Par megapacman dans le forum Access
    Réponses: 2
    Dernier message: 06/04/2006, 13h34
  4. [JTable] probleme suppression ligne
    Par lilou77 dans le forum Composants
    Réponses: 1
    Dernier message: 01/11/2005, 10h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo