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 Père-Enfant avec critères multiples sur enfants


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 30
    Points : 22
    Points
    22
    Par défaut Requête Père-Enfant avec critères multiples sur enfants
    Bonjour à tous,

    Je vais prendre un exemple concret pour baser sur une commande d'articles :

    Table COMMANDES : 
    colonne id.
    Table Articles
    colonne id
    colonne id_commande
    colonne code_article
    colonne nombre
    Quelle est la requête la "plus" optimisée) (car mes tables contiendront plusieurs millions de lignes) afin de faire la recherche suivante :
    Je veux toutes les commandes qui ont les articles :
    (code_article="A" et nombre=1) ET
    (code_article="B" et nombre=2)
    ... (je peux avoir une infinité d'articles)


    J'avais pensé à un truc du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select * from commande where id in (
    select id_commande from article where code_article="A" and nombre=1
    intersect
    select id_commande from article where code_article="B" and nombre=1')
    Mon soucis, c'est que après quelques lectures sur le net, j'ai vu que le "intersect" n'était pas très performant et qu'il vaut mieux utiliser un "intersect all", mais cela pose des soucis dans le cas de doublon.

    Avez vous une autre solution plus performante ?

    Pour info la base utilisée est Postgres

    Je vous remercie

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    Pourquoi ne pas faire directement une (ou des) jointure(s) entre commande et article ? Ou une seule jointure, et des restrictions sur code_article et nombre avec des OR ?

    Un debut de piste sera aussi donné par le plan d'execution des différentes solutions.

    Tatayo.

    P.S. concernant le nom des tables, j'aurai plutôt vu ligne_commande que article...

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 30
    Points : 22
    Points
    22
    Par défaut
    Ok merci,

    en gros quelques choses comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select * from commande 
    inner join article a1 on a1.id_commande = commande.id
    inner join article a2 on a2.id_commande = commande.id (ou a1.id_commande)
    where 
    a1.code_article="A" and a2.code_article="B" and a1.nombre=1 and a2.nombre=1
    ?

    je ne vois pas par contre comment faire avec les OR.
    si tu peux m'expliquer comment tu vois la requete ?

    PS : tu as raison pour les noms des tables, c'est pas forcément les plus parlants ! ^^

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2005
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 18
    Points : 10
    Points
    10
    Par défaut
    Bonjour

    J'ai été confronté à un problème similaire et j'ai trouvé 2 manières de le résoudre. La 1ère en utilisant les jointures comme on te l'a proposé. Seulement dans mon cas précis ce n'était pas du tout performant quand le nombre de critères au niveau le plus bas (dans ton cas sur les articles) dépassent 2 critères, car tu fais autant de jointures qu'il y a de critères. Et apparemment ça sera le cas pour toi (tu auras pas mal de critères au niveau de la table Article)

    Mais sinon la requête est la suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT C.*
    FROM Commande C
    INNER JOIN Article A1 ON C.id = A1.id_commande
    INNER JOIN Article A2 ON C.id = A2.id_commande
    WHERE (A1.codeArticle = "A" AND A1.nombre = 1)
    AND (A2.codeArticle = "B" AND A2.nombre = 2)
    La 2ème approche est d'utiliser le GROUP BY sur la table Article (si + de 1 critère dans la table Articles):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT C.*, A.commande_id
    FROM Article A
    INNER JOIN Commande C ON A.id_commande = C.id
    WHERE (
      (A.codeArticle = "A" AND A.nombre = 1)
      OR
      (A.codeArticle = "B" AND A.nombre = 2)
    )
    GROUP BY A.commande_id
    HAVING count(A.commande_id) = 2
    L'avantage de cette solution c'est d'éviter d'avoir N jointures sur Article pour N critères.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 30
    Points : 22
    Points
    22
    Par défaut
    Bonjour,

    Ok merci.
    Je vais tenter tous ceci et voir les meilleures en questions de perf !

  6. #6
    Membre expérimenté
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Points : 1 717
    Points
    1 717
    Billets dans le blog
    6
    Par défaut
    @gtaman
    ta sollicitation n'est pas claire. peux tu nous donner un jeu de données avec le résultat souhaité?
    d'avoir Pensé à voter positivement pour ceux qui vous ont aidés et surtout à mettre si le cas.
    ça encourage.

  7. #7
    Modérateur
    Avatar de Chtulus
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2008
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2008
    Messages : 3 094
    Points : 8 678
    Points
    8 678
    Par défaut
    Bonsoir,

    Vous pouvez modifier votre Modélisation ?
    « Je ne cherche pas à connaître les réponses, je cherche à comprendre les questions. »
    - Confucius -

    Les meilleurs cours, tutoriels et Docs sur les SGBD et le SQL
    Tous les cours Office
    Solutions d'Entreprise



Discussions similaires

  1. Réponses: 7
    Dernier message: 24/09/2012, 23h12
  2. Réponses: 1
    Dernier message: 04/02/2010, 20h57
  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. Requête de stocks avec critères de dates
    Par fred_vannes56 dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 13/05/2008, 16h15
  5. [MySQL] Requête avec critères multiples
    Par malabarbe dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 10/01/2008, 11h54

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