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 :

Requête avec conditions multiples (OR/AND) sur le même champ


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2013
    Messages : 24
    Par défaut Requête avec conditions multiples (OR/AND) sur le même champ
    Bonjour,
    je voudrais faire une requête pour récupérer tous les id_a qui ont pour id_b la valeur (1 OU 2) ET 4

    --------------
    | id_a | id_b |
    --------------
    | 1 | 1 |
    | 1 | 2 |
    | 1 | 4 |
    | 2 | 3 |
    | 2 | 2 |
    | 4 | 4 |

    Merci

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 134
    Par défaut
    Quelque chose comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT  src.id_a
    FROM    matable src
    WHERE   src.id_b = 4
        AND EXISTS
            (   SELECT  NULL
                FROM    matable det
                WHERE   src.id_a = det.id_a
                    AND det.id_b IN (1, 2)
            )
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Il faut une auto-jointure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT idA
    FROM la_table t1
    INNER JOIN la_table t2 ON t2.idA = t1.idA
    WHERE t1.idB = 4
    	AND t2.idB IN (1, 2)
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2013
    Messages : 24
    Par défaut
    Je sais qu'on peut récupérer les id_a qui ont pour id_b la valeur (1 ET 2 ET 4) avec cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT id_a
    FROM table
    WHERE id_b IN (1,2,4) 
    GROUP BY id_a
    HAVING COUNT(DISTINCT id_b) = 3;
    Mais pour faire (1 OU 2) ET (4), je ne sais pas si on peut partir du même principe.

    Merci

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2013
    Messages : 24
    Par défaut
    al1_24 ,

    Je faisais une requête similaire avant mais avec un WHERE IN et non un EXISTS avec un requête imbriquée mais dès que j'ai eu beaucoup de données, j'ai eu quelques soucis niveau performance....

    Je crois, mais j'en suis pas sur, qu'un des défaut de MYSQL était les requêtes imbriquées dans des WHERE IN car sur une table de plus de 100 000/200 000, ce style de requête était d'un lenteur affreuse après avec un EXISTS ça doit être pareil ?

    Merci

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2013
    Messages : 24
    Par défaut
    CinePhil,

    Je suis d'accord avec l'auto jointure mais niveau performance sur une grosse table est-ce bien ?
    Car justement je ne voulais pas partir sur ce genre de requête que ce soit avec une requête imbriqué ou avec auto jointure car je crois que son exécution est lente.
    Dite moi si je me trompe

    Je m'explique un peu plus, j'ai une table entre 500 000 et 1 000 000 de lignes donc si je dois faire un requête de ce style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT idA
    FROM la_table t1
    INNER JOIN la_table t2 ON t2.idA = t1.idA
    INNER JOIN la_table t3 ON t3.idA = t1.idA
    INNER JOIN la_table t4 ON t4.idA = t1.idA
    WHERE t1.idB = 4
    AND t2.idB IN (1, 2)
    AND t3.idB IN (100,200)
    AND t4.idB = 300

    Chaque jointure me retourne plus de 300000 lignes comment va ce comporter un telle requête?

    Merci.

  7. #7
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 134
    Par défaut
    Je ne connais pas l'optimiseur de MySQL mais je crains qu'il ne construise le sous-ensemble du IN avant d'exécuter le reste de la requête.
    Théoriquement, si tu as un index sur (id_a, id_b), toute la recherche devrait se faire sur l'index...
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  8. #8
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Tu as essayé les deux solutions qu'on t'a données ?

    La solution de al1_24 avec le EXISTS est peut-être un poil plus rapide avec un grand nombre de données.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2013
    Messages : 24
    Par défaut
    Oui j'étais passé par ce type de requête imbriqué et auto- jointure et ce n'était pas concluant.
    Mais pour pas dire n'importe quoi je vais les tester tout de suite et reviens vers vous.

    Pour tout vous dire, pour faire obtenir le résultat voulu, je passe actuellement par des tables temporaires ...
    ET la pareil niveau performance ce n'est pas trop top

    Merci pour votre aide.

  10. #10
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 953
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 953
    Par défaut
    Et la solution d'aieeeuuuuu un peu au dessus ?
    http://www.developpez.net/forums/d13...p/#post7155464

  11. #11
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    Pour repartir du même principe, vous pouvez faire comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT id_a
    FROM LaTable
    WHERE id_b IN (1,2,4) 
    GROUP BY id_a
    HAVING COUNT(DISTINCT 
    		CASE 
    			WHEN id_b IN (1,2) THEN 1
    			WHEN id_b = 4 THEN 2
    		END
    		) = 2;
    Si vous n'avez pas d’unicité sur le couple (id_a, id_b), il faudra dédoublonner les requêtes proposées par CinePhil et al1_24(avec un distinct).

    Si au contraire vous avez une contrainte d'unicité (et donc a priori les index qui vont avec...) la requête de al1_24 sera je pense plus performante...

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

Discussions similaires

  1. Requête avec condition en AND sur deux tables
    Par sologne dans le forum Requêtes
    Réponses: 3
    Dernier message: 19/05/2011, 11h09
  2. requête AND sur un même champ
    Par MrBonheur dans le forum Requêtes
    Réponses: 8
    Dernier message: 25/01/2009, 16h35
  3. Requête avec conditions multiples sur le même champ
    Par skerdreux dans le forum Langage SQL
    Réponses: 2
    Dernier message: 25/06/2008, 19h15
  4. [MySQL] Requête avec condition sur un champ
    Par nonhosonno dans le forum Langage SQL
    Réponses: 2
    Dernier message: 26/02/2007, 14h00
  5. Calcul requête avec conditions multiples
    Par Phullbrick dans le forum Access
    Réponses: 7
    Dernier message: 18/04/2006, 13h45

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