Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/02/2012, 15h58   #1
Invité de passage
 
Homme
Inscription : février 2012
Messages : 6
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 6
Points : 2
Points : 2
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 :
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 :
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 !
Etienne812 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2012, 16h07   #2
Invité de passage
 
Homme
Inscription : février 2012
Messages : 6
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 6
Points : 2
Points : 2
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 :
 DELETE FROM Table_de_depart WHERE DATE =< 2006 AND 2001 =< DATE AND NOTE = ‘NR’ ;

Je devrais obtenir :
Code :
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 :
Table_de_depart MINUS Table_deleted
, c'est-à-dire :
Code :
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 :
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 ?
Etienne812 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2012, 16h11   #3
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 316
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 316
Points : 5 822
Points : 5 822
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
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2012, 17h30   #4
Membre Expert
 
Avatar de lola06
 
Femme Laure
Consultante en Business Intelligence
Inscription : avril 2007
Messages : 987
Détails du profil
Informations personnelles :
Nom : Femme Laure
Âge : 25
Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Consultante en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : avril 2007
Messages : 987
Points : 1 700
Points : 1 700
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 :
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 :
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 !!
__________________
~ Lola ~

Ne pas oublier :
et aussi :
lola06 est déconnecté   Envoyer un message privé Réponse avec citation 30
Vieux 10/02/2012, 18h14   #5
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 688
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 688
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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 :
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');
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 10/02/2012, 21h49   #6
Rédacteur
 
Homme Salim
Développeur et DBA Oracle
Inscription : octobre 2006
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Salim
Localisation : Canada

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

Informations forums :
Inscription : octobre 2006
Messages : 872
Points : 1 100
Points : 1 100
Bonjour,

Une autre solution sans scanner la table Matble deux fois.

Code :
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 :
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.
__________________
Publications: http://schelabi.developpez.com/
salim11 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 11/02/2012, 00h18   #7
Membre Expert
 
Avatar de lola06
 
Femme Laure
Consultante en Business Intelligence
Inscription : avril 2007
Messages : 987
Détails du profil
Informations personnelles :
Nom : Femme Laure
Âge : 25
Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Consultante en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : avril 2007
Messages : 987
Points : 1 700
Points : 1 700
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 :
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.
__________________
~ Lola ~

Ne pas oublier :
et aussi :
lola06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2012, 10h36   #8
Invité de passage
 
Homme
Inscription : février 2012
Messages : 6
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 6
Points : 2
Points : 2
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
Etienne812 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2012, 20h50   #9
Rédacteur
 
Homme Salim
Développeur et DBA Oracle
Inscription : octobre 2006
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Salim
Localisation : Canada

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

Informations forums :
Inscription : octobre 2006
Messages : 872
Points : 1 100
Points : 1 100
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.
__________________
Publications: http://schelabi.developpez.com/
salim11 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2012, 22h56   #10
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 688
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 688
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h23.


 
 
 
 
Partenaires

Hébergement Web