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

Langage SQL Discussion :

Suppression avec sous-requête conditionnelle


Sujet :

Langage SQL

  1. #1
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut Suppression avec sous-requête conditionnelle
    Bonjour,

    Environnement : Interbase 6

    Suite à l'article de SQLpro sur l'ordre DELETE, je cherche à écrire une requête de suppression avec sous-requête conditionnelle CONFORME vis-à-vis de la norme SQL.

    Ma requête de sélection que je veux transformer en requête de suppression est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT CDE_CODRESA, CDE_NOENREG
    FROM ENTETES_RESA
    GROUP BY CDE_CODRESA, CDE_NOENREG
    HAVING COUNT(*) > 1
    Sous Oracle, je ferais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    DELETE FROM ENTETES_RESA
    WHERE       (CDE_CODRESA,
                 CDE_NOENREG) = (SELECT   CDE_CODRESA,
                                          CDE_NOENREG
                                 FROM     ENTETES_RESA
                                 GROUP BY CDE_CODRESA,
                                          CDE_NOENREG
                                 HAVING   COUNT(*) > 1)
    Mais comment faire pour les autres SGBD dont Interbase qui ne possèdent pas le constructeur de lignes valuées ?
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  2. #2
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Solution très inélégante et qui demande des précautions...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    DELETE FROM ENTETES_RESA 
    WHERE CDE_CODRESA || '$$' || CDE_NOENREG = (SELECT   CDE_CODRESA || '$$' || CDE_NOENREG
                                                FROM     ENTETES_RESA 
                                                GROUP BY CDE_CODRESA || '$$' || CDE_NOENREG
                                                HAVING   COUNT(*) > 1)
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  3. #3
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Citation Envoyé par Médiat
    Solution qui demande des précautions...
    C'est-à-dire ?

    Concernant le :
    Citation Envoyé par Médiat
    Je suis d'accord et je m'attendais à quelque chose de plus...
    "formel" !
    Merci de ton aide.
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  4. #4
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Bonjour,

    J'ai ça à proposer...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    DELETE FROM ENTETES_RESA
    WHERE EXISTS
    (
    SELECT 1  
    FROM 	ENTETES_RESA S
    WHERE 	S.CDE_CODRESA = ENTETES_RESA.CDE_CODRESA
    AND	S.CDE_NOENREG = ENTETES_RESA.CDE_NOENREG
    GROUP BY S.CDE_CODRESA, 
          	S.CDE_NOENREG 
    HAVING   COUNT(*) > 1);
    );

  5. #5
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    TheLeadingEdge : c'est justement une jointure avec la table concernée par l'instruction DELETE que je veux éviter car c'est ce que j'avais l'habitude de faire jusqu'à ce que SQLpro me signale que cette syntaxe est HORS de la norme SQL.
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  6. #6
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Re,

    M'enfin!! T sur ? :o
    Il me semblait que ce n'étaient que les comparaisons de ligne qui étaient hors norme
    ie :
    ...CDE_CODRESA,
    CDE_NOENREG) = (SELECT CDE_CODRESA,
    CDE_NOENREG ...
    pas les jointures
    ie :
    WHERE S.CDE_CODRESA = ENTETES_RESA.CDE_CODRESA
    AND S.CDE_NOENREG = ENTETES_RESA.CDE_NOENREG
    Enfin si c SQLPro qui l'a dit, g plus qu'a réviser moi

  7. #7
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Citation Envoyé par TheLeadingEdge
    M'enfin!! T sur ?
    Tu trouveras la contestation de SQLpro ici : http://www.developpez.net/forums/vie...date+norme+sql
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  8. #8
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Holala, dans quoi je me suis embarqué moi ...
    Bon j'ai du taf à finir là...je lirai tout ça à tête reposée 1 peu plus tard

    A +

  9. #9
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Citation Envoyé par Magnus
    Citation Envoyé par Médiat
    Solution qui demande des précautions...
    C'est-à-dire ?
    Tu as remarqué que j'ai mis au milieu des deux champs un '$$' pour éviter que '12' || '3' = '1' || '23', mais cela ne fonctionne que si il n'y a pas de $ dans les colonnes concernées.

    Citation Envoyé par Magnus
    Concernant le :
    Citation Envoyé par Médiat
    Je suis d'accord et je m'attendais à quelque chose de plus...
    "formel" !
    Merci de ton aide.
    Merci de ton merci, mais je ne me souviens plus de ce à quoi tu fais allusion...
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  10. #10
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    >Magnus :
    D'après [ce que j'ai compris ...] de ce que j'ai lu :
    j'ai appris que les comparaisons de ligne/constructeur de lignes valuées sont inscrits à la norme de 92 (j'avais donc bien besoin d'1 révision ;-) )
    j'ai relu soigneusement le post que tu m'a indiqué.
    Et il me semble que SQLPro ne fais état que de l'alias qui n'est pas autorisé par la norme ds 1 ordre DELETE, et pas de la requête corrélée.
    Ds la s/requête l'utilisation d'1 alias étant possible je ne vois pas ce qui empêche de l'utiliser (la s/requête) puisque même sans alias sur la table à mette à jour il n'y a pas d'ambiguité possible sur les noms de colonne.
    Maintenant ce n'est que mon interprétation ...

    Bonne soirée

  11. #11
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Citation Envoyé par Médiat
    Tu as remarqué que j'ai mis au milieu des deux champs un '$$' pour éviter que '12' || '3' = '1' || '23', mais cela ne fonctionne que si il n'y a pas de $ dans les colonnes concernées.
    Intuitivement, c'est ce que je m'étais dit mais je ne vois pas de contre exemple. Ceci dit, comment tu fais lorsqu'une des colonnes contient des '$' ?

    Citation Envoyé par TheLeadingEdge
    D'après [ce que j'ai compris ...] de ce que j'ai lu :
    j'ai appris que les comparaisons de ligne/constructeur de lignes valuées sont inscrits à la norme de 92
    Je n'ai jamais dit que le constructeur de lignes valuées ne faisait pas partie de la norme SQL mais en tout cas de ce que j'ai pu constaté tous les SGBD ne l'implémentent pas (dans ce cas comment écrire une instruction équivalente ?)

    Citation Envoyé par TheLeadingEdge
    Ds la s/requête l'utilisation d'1 alias étant possible je ne vois pas ce qui empêche de l'utiliser (la s/requête) puisque même sans alias sur la table à mette à jour il n'y a pas d'ambiguité possible sur les noms de colonne
    Je suis entièrement d'accord mais comment écrire la requête de suppression de mon 1er post quand on ne dispose pas du constructeur de lignes valuées (et sans passer par la solution de Médiat of course) ?
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  12. #12
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Citation Envoyé par Magnus
    Citation Envoyé par Médiat
    Tu as remarqué que j'ai mis au milieu des deux champs un '$$' pour éviter que '12' || '3' = '1' || '23', mais cela ne fonctionne que si il n'y a pas de $ dans les colonnes concernées.
    Intuitivement, c'est ce que je m'étais dit mais je ne vois pas de contre exemple. Ceci dit, comment tu fais lorsqu'une des colonnes contient des '$' ?
    Tu mets '££', ou '$£µ' ou n'importe quelle chaîne qui ne risque pas de se trouver dans les colonnes sélectées
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  13. #13
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Citation Envoyé par Médiat
    Tu mets '££', ou '$£µ' ou n'importe quelle chaîne qui ne risque pas de se trouver dans les colonnes sélectées
    Ok

    Je pense avoir trouvé un exemple illustrant le problème lorsque les caractères de concaténation sont contenus dans au moins une des colonnes de corrélation :
    Supposons les 3 enregistrements suivants dans la table ENTETES_RESA :
    CDE_CODRESA / CDE_NOENREG
    ------- / -------
    A$ / $B -- doit être supprimé
    A$ / $B -- doit être supprimé
    A$$ / B -- NE doit PAS être supprimé

    La concaténation avec '$$' produit la "confusion" suivante :
    CDE_CODRESA / CDE_NOENREG / CDE_CODRESA || '$$' || CDE_NOENREG
    ------- / ------- / -------
    A$ / $B / A$$$$B
    A$ / $B / A$$$$B
    A$$ / B / A$$$$B
    Conclusion : Médiat >> la requête que tu as proposée me satisfait même si je m'attendais à quelque chose de plus formel (je ne pense pas que l'on me proposera autre chose hormis peut être SQLpro ?) donc ce n'est pas la peine de laisser le sujet ouvert.

    Merci à vous 2.
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  14. #14
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Bonjour,

    Citation Envoyé par Magnus
    TheLeadingEdge a écrit:
    D'après [ce que j'ai compris ...] de ce que j'ai lu :
    j'ai appris que les comparaisons de ligne/constructeur de lignes valuées sont inscrits à la norme de 92
    Je n'ai jamais dit que le constructeur de lignes valuées ne faisait pas partie de la norme SQL mais en tout cas de ce que j'ai pu constaté tous les SGBD ne l'implémentent pas (dans ce cas comment écrire une instruction équivalente ?)
    Non, c'est moi qui le pensait... A tort

    1>
    SELECT *
    FROM ENTETES_RESA
    WHERE EXISTS
    (
    SELECT COUNT(*)
    FROM ENTETES_RESA S
    WHERE S.CDE_CODRESA = ENTETES_RESA.CDE_CODRESA
    AND S.CDE_NOENREG = ENTETES_RESA.CDE_NOENREG
    GROUP BY S.CDE_CODRESA,
    S.CDE_NOENREG
    HAVING COUNT(*) > 1
    );

    2>
    SELECT *
    FROM ENTETES_RESA
    WHERE ( CDE_CODRESA, CDE_NOENREG) =
    (
    SELECT S.CDE_CODRESA,
    S.CDE_NOENREG
    FROM ENTETES_RESA S
    GROUP BY CDE_CODRESA,
    CDE_NOENREG
    HAVING COUNT(*) > 1
    );
    Pour moi seule la rq N° 2 est basée sur 1 'row value contructor, c'est pour ça que je t'ai proposé la première. Mais je suis rendu compte qu'elle ne fonctionnait pas non plus avec IB (mais ça tu le savais déjà ...), alors que sur la plupart des SGBDr que je connais elle fonctionne.

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

Discussions similaires

  1. [MySQL] Condition IN avec sous requête
    Par emphase dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 21/02/2007, 01h43
  2. [MySQL] erreur avec sous-requête
    Par Piou2fois dans le forum Langage SQL
    Réponses: 4
    Dernier message: 04/02/2006, 13h44
  3. DELETE avec sous-requête
    Par say dans le forum Langage SQL
    Réponses: 2
    Dernier message: 27/04/2005, 08h20
  4. INTERBASE: DELETE avec sous requete conditionnelle
    Par Papino dans le forum InterBase
    Réponses: 6
    Dernier message: 17/02/2005, 22h55
  5. suppression avec sous requête conditionnelle
    Par melmel dans le forum Requêtes
    Réponses: 8
    Dernier message: 18/03/2004, 23h20

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