none
(Visual Studio 2008) Select sur plusieurs tables, avec conditions RRS feed

  • Question

  • Bonjour,

    Cela fait plusieurs jours que "galère" !

    Je consulte le NET, je fais moult et moult tests, sans arriver à mes fins …

    J'ai deux tables

    ARTICLE   champs KEY1 et NOM

    COMPOSANT   champs KEY1, KEY2 et VALEUR

    ARTICLE

    KEY1         NOM

    1                TOTO

    2                TATA

    COMPOSANT

    KEY1         KEY2                VALEUR

    1                 10                     1000

    1                 20                     2000

    2                 10                      1500

    2                 15                     1600

    Si je sélectionne les articles qui ont les composants 10 OU 20, j'obtiens l'article 1 et l'article 2

    rst.Open("select COMPOSANT.Key1 , COMPOSANT.Key2, COMPOSANT.VALEUR" & _

                                     "ARTICLE.Key1, ARTICLE.NOM " & _

    "FROM   ARTICLE INNER JOIN COMPOSANT ON ARTICLE.Key1 = COMPOSANT.Key1 " & _

    "WHERE ( (COMPOSANT.Key2= 34000) OR (COMPOSANT.Key2= 25000) ) " & _

                             "ORDER by ARTICLE.NOM", cnc)

    Mais si je veux sélectionner les articles qui ont le composant 10 ET 15, je n'obtiens plus rien !

    rst.Open("select COMPOSANT.Key1 , COMPOSANT.Key2, COMPOSANT.VALEUR" & _

                                     "ARTICLE.Key1, ARTICLE.NOM " & _

    "FROM   ARTICLE INNER JOIN COMPOSANT ON ARTICLE.Key1 = COMPOSANT.Key1 " & _

    "WHERE ( (COMPOSANT.Key2= 34000) AND (COMPOSANT.Key2= 25000) ) " & _

                             "ORDER by ARTICLE.NOM", cnc)

    Alors que l'article 2 a bien le composant 10 ET 15 !

    Pouvez-vous m'aider à trouver la bonne syntaxe ?


    Cordialement SC

    dimanche 9 juin 2013 17:04

Réponses

  • Bonjour,

    C'est normal... Dans votre clause WHERE vous exprimez une condition qui signifie :

    "Pour chaque composant, je recherche les composants qui ont à la fois une Key2 = 34000 et Key2 = 25000". Ce qui est par définition toujours faux...

    Vous devez faire 2 jointures :

    SELECT
         *
    FROM
         ARTICLE
       INNER JOIN
         COMPOSANT AS C1 ON (ARTICLE.Key1 = C1.Key1)
       INNER JOIN
         COMPOSANT AS C2 ON (ARTICLE.Key1 = C2.Key1)
    WHERE
       C1.Key2 = 34000 AND C2.Key2 = 2500
       

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte logiciel/Consultant/Formateur Freelance
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0

    dimanche 9 juin 2013 22:06
    Modérateur
  • Bonjour,

    Un grand merci !

    Je sentais bien que je faisais un illogisme, mais je n'arrivais pas à cerner correctement le problème

    De plus j'aurai du penser plus tôt a créer un DATASET, et a configurer la requête, ce qui m'aurait de suite la bonne syntaxe !

    Après bien des efforts, la voici, avec trois tables

    FOOD_GROUP      lien sur FOOD par ORIGGPCD

    FOOD                  lien sur FOOD_GROUP par ORIGGPCD, lien sur COMPILED_DATA par ORIGFDCD

    COMPILED_DATA lien sur FOOD par ORIGFDCD

                rst.Open("SELECT  FOOD.ORIGFDCD, FOOD.ORIGFDNM, FOOD.ORIGGPCD, FOOD.TriMorpho, " & _
                                 "COMPILED_DATA.ORIGFDCD AS F1, COMPILED_DATA.ORIGCPCD AS C1,  COMPILED_DATA.SELVAL AS V1, " & _
                                 "COMPILED_DATA_1.ORIGFDCD AS F2, COMPILED_DATA_1.ORIGCPCD AS C2, COMPILED_DATA_1.SELVAL AS V2,  " & _
                                 "FOOD_GROUPS.FamMorphoNEW, FOOD_GROUPS.FamMorphoLibNEW " & _
                         "FROM (((FOOD INNER JOIN COMPILED_DATA ON FOOD.ORIGFDCD = COMPILED_DATA.ORIGFDCD) " & _
                                     "INNER Join COMPILED_DATA COMPILED_DATA_1 ON FOOD.ORIGFDCD = COMPILED_DATA_1.ORIGFDCD) " & _
                                     "INNER JOIN FOOD_GROUPS ON FOOD.ORIGGPCD = FOOD_GROUPS.ORIGGPCD) " & _
                         "WHERE  (COMPILED_DATA.SELVAL <> '0') " & _
                         "AND    (COMPILED_DATA_1.SELVAL <> '0') " & _
                         "AND    (COMPILED_DATA_1.ORIGCPCD = 25000)" & _
                         "AND    (COMPILED_DATA.ORIGCPCD = 34000)" & _
                         "ORDER BY FOOD_GROUPS.FamMorphoNEW, FOOD.ORIGGPCD, FOOD.ORIGFDCD, COMPILED_DATA.ORIGCPCD", cnc)

    Le nouveau problème est que j'avais prévu de remplir de suite un DATAGRIDVIEW, avec les composants les uns en dessous des autres, ce qui n'est plus possible car la requête me donne une ligne

    Et il va falloir que je limite l'utilisateur à 6 composants, car il faut les décrire un par un ...

    Encore merci


    Cordialement SC

    • Marqué comme réponse Florin Ciuca mercredi 12 juin 2013 07:35
    lundi 10 juin 2013 08:50

Toutes les réponses

  • Bonjour,

    C'est normal... Dans votre clause WHERE vous exprimez une condition qui signifie :

    "Pour chaque composant, je recherche les composants qui ont à la fois une Key2 = 34000 et Key2 = 25000". Ce qui est par définition toujours faux...

    Vous devez faire 2 jointures :

    SELECT
         *
    FROM
         ARTICLE
       INNER JOIN
         COMPOSANT AS C1 ON (ARTICLE.Key1 = C1.Key1)
       INNER JOIN
         COMPOSANT AS C2 ON (ARTICLE.Key1 = C2.Key1)
    WHERE
       C1.Key2 = 34000 AND C2.Key2 = 2500
       

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte logiciel/Consultant/Formateur Freelance
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0

    dimanche 9 juin 2013 22:06
    Modérateur
  • Bonjour,

    Un grand merci !

    Je sentais bien que je faisais un illogisme, mais je n'arrivais pas à cerner correctement le problème

    De plus j'aurai du penser plus tôt a créer un DATASET, et a configurer la requête, ce qui m'aurait de suite la bonne syntaxe !

    Après bien des efforts, la voici, avec trois tables

    FOOD_GROUP      lien sur FOOD par ORIGGPCD

    FOOD                  lien sur FOOD_GROUP par ORIGGPCD, lien sur COMPILED_DATA par ORIGFDCD

    COMPILED_DATA lien sur FOOD par ORIGFDCD

                rst.Open("SELECT  FOOD.ORIGFDCD, FOOD.ORIGFDNM, FOOD.ORIGGPCD, FOOD.TriMorpho, " & _
                                 "COMPILED_DATA.ORIGFDCD AS F1, COMPILED_DATA.ORIGCPCD AS C1,  COMPILED_DATA.SELVAL AS V1, " & _
                                 "COMPILED_DATA_1.ORIGFDCD AS F2, COMPILED_DATA_1.ORIGCPCD AS C2, COMPILED_DATA_1.SELVAL AS V2,  " & _
                                 "FOOD_GROUPS.FamMorphoNEW, FOOD_GROUPS.FamMorphoLibNEW " & _
                         "FROM (((FOOD INNER JOIN COMPILED_DATA ON FOOD.ORIGFDCD = COMPILED_DATA.ORIGFDCD) " & _
                                     "INNER Join COMPILED_DATA COMPILED_DATA_1 ON FOOD.ORIGFDCD = COMPILED_DATA_1.ORIGFDCD) " & _
                                     "INNER JOIN FOOD_GROUPS ON FOOD.ORIGGPCD = FOOD_GROUPS.ORIGGPCD) " & _
                         "WHERE  (COMPILED_DATA.SELVAL <> '0') " & _
                         "AND    (COMPILED_DATA_1.SELVAL <> '0') " & _
                         "AND    (COMPILED_DATA_1.ORIGCPCD = 25000)" & _
                         "AND    (COMPILED_DATA.ORIGCPCD = 34000)" & _
                         "ORDER BY FOOD_GROUPS.FamMorphoNEW, FOOD.ORIGGPCD, FOOD.ORIGFDCD, COMPILED_DATA.ORIGCPCD", cnc)

    Le nouveau problème est que j'avais prévu de remplir de suite un DATAGRIDVIEW, avec les composants les uns en dessous des autres, ce qui n'est plus possible car la requête me donne une ligne

    Et il va falloir que je limite l'utilisateur à 6 composants, car il faut les décrire un par un ...

    Encore merci


    Cordialement SC

    • Marqué comme réponse Florin Ciuca mercredi 12 juin 2013 07:35
    lundi 10 juin 2013 08:50