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 :

Supprimer un groupe sur la base d'un critère rempli par un membre du groupe


Sujet :

SQL Oracle

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 6
    Points : 6
    Points
    6
    Par défaut Supprimer un groupe sur la base d'un critère rempli par un membre du groupe
    Bonjour,

    Je cherche à écrire une procédure qui me permette de supprimer d'une table tout un groupe ayant un même nom (ou autre critère) pour lequel une des lignes du groupe seulement remplit un certain critère :

    J’ai la table suivante 'Table_de_depart'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    NOM		NOTE		DATE		RANG (de la note)
    Alpha		AA		2006		3
    Alpha		NR		1998		27
    Alpha		A+		2004		5
    Beta		NR		2004		27
    Beta		BB		2006		12
    Beta		BB+		2001		11
    Je cherche à obtenir tous les noms qui ont une note entre 2001 et 2006, mais qui n’ont pas de NR entre ces deux dates, c'est-à-dire les résultats suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    NOM		NOTE		DATE		RANG (de la note)
    Alpha		AA		2006		3
    Alpha		A+		2004		5
    Toutes les entrées ‘Beta’ ont été supprimées, car Beta contient au moins une note NR entre les dates 2001 et 2006

    Merci pour votre aide !
    NB : je débute en SQL, merci d’être très pédagogue et explicite dans vos réponses !

  2. #2
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Voici mon idée, mais toute autre idée est la bienvenue :

    Je crée une table_deleted où je supprime tous les résultats contenant ‘NR’ entre les 2 dates désirées :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
     DELETE from Table_de_depart where DATE =< 2006 and 2001 =< DATE and NOTE = ‘NR’ ;

    Je devrais obtenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    NOM		NOTE		DATE		RANG (de la note)
    Alpha		AA		2006		3
    Alpha		NR		1998		27
    Alpha		A+		2004		5
    Beta		BB		2006		12
    Beta		BB+		2001		11

    J’appelle Table_deleted ce résultat : mais je ne sais pas faire ça ! j’ai posté un message à ce sujet : « Créer une table à partir des résultats d’un DELETE ? »

    J’appelle Table_intermédiaire le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Table_de_depart MINUS Table_deleted
    , c'est-à-dire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    NOM		NOTE		DATE		RANG
    Beta		NR		2004		27

    Maintenant je supprime de la table_de_depart tous les NOM qui se retrouvent dans la table intermédiaire, je filtre aussi sur les dates (2001 =< DATE =< 2006) et j’obtiens le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    NOM		NOTE		DATE		RANG
    Alpha		AA		2006		3
    Alpha		A+		2004		5
    Est-ce que cela vous semble correct comme démarche ? Y a-t-il plus simple ? Comment créer la table Table_deleted ?

  3. #3
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Pour l’instant essayez d’écrire la requête qui à partir de votre jeux d’essai trouve tous les enregistrements correspondantes à vos critères : une note entre 2001 et 2006, mais qui n’ont pas de NR entre ces deux dates

  4. #4
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Je pense qu'il vaut mieux prendre le problème à l'envers.

    - tu sélectionnes ta ligne avec NR et date > 2001 et < 2006

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT nom, note, date, rang
    FROM MaTable
    WHERE date BETWEEN 2001 AND 2006
    AND note = 'NR'
    - tu récupères juste le nom que tu supprime de ta sélection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT *
    FROM MaTable
    WHERE nom NOT IN (SELECT DISTINCT nom
    FROM MaTable
    WHERE date BETWEEN 2001 AND 2006
    AND note = 'NR')
    AND date BETWEEN 2001 AND 2006
    Est-ce que cette requête vous donne le bon résultat ?

    Au passage j'espère que 'date' n'est pas le vrai nom de ta colonne !!

  5. #5
    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
    Il manque encore un filtre dans la requête de lola06, et le distinct est inutile dans les sous-requêtes IN / NOT IN :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
      FROM MaTable
     WHERE date BETWEEN 2001 AND 2006
       AND NOT <> 'NR'
       AND nom NOT IN (SELECT nom
                         FROM MaTable
                        WHERE date BETWEEN 2001 AND 2006
                          AND note = 'NR');

  6. #6
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Points : 1 197
    Points
    1 197
    Par défaut
    Bonjour,

    Une autre solution sans scanner la table Matble deux fois.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    WITH matable1 AS
         (SELECT nom, note, dt, rang,
                 COUNT (CASE
                           WHEN note = 'NR'
                              THEN 1
                        END) OVER (PARTITION BY nom) exist
            FROM matable
           WHERE dt BETWEEN 2001 AND 2006)
    SELECT nom, note, dt, rang, exist
      FROM matable1
     WHERE exist = 0
    La démonstration
    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
     
    WITH matable AS
         (SELECT 'Alpha' nom, 'AA' note, 2006 dt, 3 rang
            FROM DUAL
          UNION ALL
          SELECT 'Alpha', 'NR', 1998, 27
            FROM DUAL
          UNION ALL
          SELECT 'Alpha', 'A+', 2004, 5
            FROM DUAL
          UNION ALL
          SELECT 'Beta', 'NR', 2004, 27
            FROM DUAL
          UNION ALL
          SELECT 'Beta', 'BB', 2006, 12
            FROM DUAL
          UNION ALL
          SELECT 'Beta', 'BB+', 2001, 11
            FROM DUAL),
         matable1 AS
         (SELECT nom, note, dt, rang,
                 COUNT (CASE
                           WHEN note = 'NR'
                              THEN 1
                        END) OVER (PARTITION BY nom) exist
            FROM matable
           WHERE dt BETWEEN 2001 AND 2006)
    SELECT nom, note, dt, rang, exist
      FROM matable1
     WHERE exist = 0
     
     
    NOM   NOT         DT       RANG      EXIST
    ----- --- ---------- ---------- ----------
    Alpha A+        2004          5          0
    Alpha AA        2006          3          0
     
     
    2 rows selected.

  7. #7
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Il manque encore un filtre dans la requête de lola06, et le distinct est inutile dans les sous-requêtes IN / NOT IN :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
      FROM MaTable
     WHERE date BETWEEN 2001 AND 2006
       AND NOT <> 'NR'
       AND nom NOT IN (SELECT nom
                         FROM MaTable
                        WHERE date BETWEEN 2001 AND 2006
                          AND note = 'NR');
    Est ce que le NOTE <> 'NR' est vraiment utile ? Car ma sous-requête permet de ne pas sélectionner un groupe dès qu'un NR est dedans. Et donc il n'est pas possible qu'il réapparaisse par la suite.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Merci beaucoup à vous tous, Lola06, Waldar et Salim11 !!
    Je me doutais bien que je prenais le problème à l'envers.
    J'utilise la requête de Waldar cela fonctionne très bien. La requête de Lola06 aussi fonctionne et retourne les mêmes résultats. Ce que fait Salim me paraît plus compliqué et je ne comprends pas vraiment.

    Merci infiniment encore !

    PS : il faut bien sûr lire NOTE au lieu de NOT dans la requête de Waldar, pour le nom de colonne, et @Lola06 : oui ma colonne ne s'appelle évidemment pas DATE, j'essayais juste de donner des noms très explicites

  9. #9
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Points : 1 197
    Points
    1 197
    Par défaut
    Citation Envoyé par Etienne812 Voir le message
    Ce que fait Salim me paraît plus compliqué et je ne comprends pas vraiment.
    Ma requête est vraiment simple:

    1-Je comptabilise dans ma première requête le nombre de fois qu'apparait note = 'NR' par nom avec la dt entre 2001 et 2006.

    2- si ce nombre (exist)=0 alors j'obtiens tous les noms qui ont une note entre 2001 et 2006, mais qui n’ont pas de NR

    Si tu as des questions n'hésite pas.

    Cordialement Salim.

  10. #10
    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
    Citation Envoyé par lola06 Voir le message
    Est ce que le NOTE <> 'NR' est vraiment utile ? Car ma sous-requête permet de ne pas sélectionner un groupe dès qu'un NR est dedans. Et donc il n'est pas possible qu'il réapparaisse par la suite.
    Entre le jeu de départ et le résultat souhaité, tout le groupe beta est exclu (par le not in), mais parmi les informations du groupe alpha la note NR (deuxième ligne) disparaît aussi.
    Mais l'essentiel de la requête c'est bien le NOT IN.

    La solution de salim11 est très bien aussi, probablement de plus en plus performante avec une augmentation de volumétrie.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/04/2015, 15h31
  2. Réponses: 7
    Dernier message: 07/08/2012, 15h24
  3. [XL-2010] Recherche de fichiers sur la base de différents critères
    Par venusfr dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 23/05/2012, 14h12
  4. Réponses: 3
    Dernier message: 25/08/2011, 11h59
  5. Réponses: 8
    Dernier message: 18/09/2007, 09h55

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