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

Requêtes et SQL. Discussion :

La query bug quand il y a du texte dans ma formule de concaténation malgré les filtres


Sujet :

Requêtes et SQL.

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Chef projet SAP
    Inscrit en
    Juin 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef projet SAP

    Informations forums :
    Inscription : Juin 2020
    Messages : 3
    Points : 1
    Points
    1
    Par défaut La query bug quand il y a du texte dans ma formule de concaténation malgré les filtres
    Hello,
    Problème bizarre. J'ai une query 2 qui dépend d'une query 1 et dans un cas précis, alors qu'il devrait ramener la valeur "null", la query 2 ramène seulement la partie texte d'une formule de concaténation quand il s'agit d'une entrée "filtrée" dans la query source (1) et tout le résultat de la formule si l'entrée n'est pas filtrée. Ce bug ne se produit pas si je n'ai pas de portion "texte" dans ma formule de départ.
    je tiens à mon left join pour d'autres raisons. J'ai contourné en changeant "formule + filtre" en formule intégrant le filtre par un "if" mais c'est pas top.


    voilà la description de ma base, simplifiée pour isoler le problème:
    TABLE1 pays et règle pour donner un nom à la zone pays
    • "COUNTRY" - short text (Country value 2 characters)
    • "RULE" - short text (value est soit CTY soit REG)



    QUERY1 utilise TABLE1 uniquement - formule va donner le nom de la zone et filtrer uniquement les pays dont la "rule" est "CTY" (une autre query fera de même pour la rule "REG"
    • [TABLE1].[COUNTRY]
    • [TABLE1].[RULE] criteria "CTY"
    • ZOne_name:[COUNTRY] & "00000000"



    le résultat montre uniquement les entrées RULE="CTY", jusque la tout va bien
    mais ça déconne ensuite

    TABLE2 (liste de clients et leur pays)
    • "PARNTER" - short text (10 digit numbers)
    • "PAYS" - short text (Country value 2 characters)



    QUERY2, utilise QUERY1 & TABLE2 pour rapatrier le nom de la zone pour chaque client
    • Left Join TABLE2 "PAYS" to QUERY1 "COUNTRY",
    • [TABLE2].[PARTNER]
    • [QUERY1].[Zone_name]



    résultat:
    si PAYS est dans la liste des pays filtrés (donc avec RULE=CTY" dans QUERY1, dans QUERY1.ZONE_name il ramène par exemple "USF0000000" - good
    mais si PAYS n'est pas dans le résultat de QUERY1 (donc RULE <> "CTY"), dans QUERY1.ZONE_name le résultat donne "F0000000" ?????? ça devrait être vide!!

    si au lieu de ZOne_name:[COUNTRY] & "00000000" dans QUERY1 je mets par exemple ZOne_name:[COUNTRY] & [RULE], pour un pays avec avec RULE<> CTY dans QUERY1 j'ai bien le résultat = null

    comme si c'était la portion text qui mettait le bazar

    Merci pour votre aide, en attendant j'ai changé la formule de "zone name" pour intégrer le "iif rule = cty" au lieu de le mettre comme un filtre! (peut etre Access ne supporte pas ma première façon de faire mais étrange que le bug ne soit qu'avec une portion texte)


    SQL QUERY1:

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        SELECT TABLE1.COUNTRY, TABLE1.RULE, TABLE1.COUNTRY & "F0000000" AS ZONE_Name
        FROM TABLE1
        WHERE (((TABLE1.RULE)="CTY"));


    SQL QUERY2:

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        SELECT TABLE2.PARTNER, TABLE2.PAYS, QUERY1.ZONE_NAME, 
        FROM TABLE2 LEFT JOIN QUERY1 ON TABLE2.PAYS = QUERY1.COUNTRY;

  2. #2
    Expert confirmé
    Homme Profil pro
    retraité
    Inscrit en
    Juin 2012
    Messages
    3 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : retraité
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Juin 2012
    Messages : 3 183
    Points : 5 515
    Points
    5 515
    Par défaut
    NULL & "F0000000" = "F0000000" !
    Aussi soit ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT TABLE1.COUNTRY, TABLE1.RULE, TABLE1.COUNTRY & "F0000000" AS ZONE_Name
    FROM TABLE1
    WHERE ((TABLE1.RULE="CTY") AND (TABLE1.COUNTRY & "" <> ""));
    ou ceci si vous souhaitez avoir les Null
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT TABLE1.COUNTRY, TABLE1.RULE, IIF(TABLE1.COUNTRY & "" = "", NULL, TABLE1.COUNTRY & "F0000000") AS ZONE_Name
    FROM TABLE1
    WHERE (TABLE1.RULE="CTY");
    Cordialement

  3. #3
    Nouveau Candidat au Club
    Femme Profil pro
    Chef projet SAP
    Inscrit en
    Juin 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef projet SAP

    Informations forums :
    Inscription : Juin 2020
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Merci,

    il n'y a pas de valeur Null dans ma liste de pays j'ai revérifié. et j'ai qd meme testé les 2 options cela ne change rien.
    la seule alternative est de faire en sorte qu'il n'y ait pas de valeur pour les pays dont la Rule est <> CTY (SQL ci dessous).
    Dans ce cas cela peut repondre au besoin mais c'est contourner le pb

    pourquoi Access renvoi bien "null" si je concatene (TABLE1.COUNTRY & TABLE1.RULE)
    mais renvoi "F0000000" si je concatene (TABLE1.COUNTRY & "F0000000") c'est louche tout ca

    je contourne comme cela mais je me demnde s'il n'y a pas un parametre de query ou qqch dans le genre que je rate

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT TABLE1.COUNTRY, TABLE1.RULE, IIF(TABLE1.RULE = "CTY", TABLE1.COUNTRY & "F0000000",null) AS ZONE_Name
    FROM TABLE1
    WHERE (TABLE1.RULE="CTY");

  4. #4
    Rédacteur/Modérateur
    Avatar de loufab
    Homme Profil pro
    Entrepreneur en solutions informatiques viables et fonctionnelles.
    Inscrit en
    Avril 2005
    Messages
    12 006
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Entrepreneur en solutions informatiques viables et fonctionnelles.
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2005
    Messages : 12 006
    Points : 24 598
    Points
    24 598
    Par défaut
    Bonjour,

    A moins d'être passé à côté de quelque chose, il me semble que cette requête fonctionne bien.

    En effet vous demandez d'inclure toute les lignes de la table2 et seulement celle qui correspondent dans la Query1.
    Dans le showplan on voit comment il procède :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    - Inputs to Query -
    Table 'Table2'
    Table 'Table1'
    - End inputs to Query -
     
    01) Restrict rows of table Table1
          by scanning
          testing expression "Table1.RULE="CTY""
    02) Sort result of '01)'
    03) Outer Join table 'Table2' to result of '02)'
          using temporary index
          join expression "Table2.PAYS=QUERY1.COUNTRY"
    Là où il n'y a pas de correspondance il ne met rien, sauf si vous indiquez une valeur, dans ce cas il renvoi cette valeur, puis que l'obligation de table1 le lui ordonne.

    Si vous ne voulez pas ces tuples, vous devez soit utiliser un inner join, soit une requête unique comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT Table2.PARTNER, Table2.PAYS, Table1.RULE, [TABLE1].[COUNTRY] & "F0000000" AS [zone]
    FROM Table2 LEFT JOIN Table1 ON Table2.PAYS = Table1.COUNTRY
    WHERE (((Table1.RULE)="CTY"));
    Dans ce cas le showplan sera celui-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    --- temp query ---
     
    - Inputs to Query -
    Table 'Table2'
    Table 'Table1'
    - End inputs to Query -
     
    01) Restrict rows of table Table1
          by scanning
          testing expression "Table1.RULE="CTY""
    02) Sort table 'Table2'
    03) Inner Join result of '01)' to result of '02)'
          using temporary index
          join expression "Table1.COUNTRY=Table2.PAYS"
    Le même que pour un Inner join avec la QUERY1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    --- temp query ---
     
    - Inputs to Query -
    Table 'Table2'
    Table 'Table1'
    - End inputs to Query -
     
    01) Restrict rows of table Table1
          by scanning
          testing expression "Table1.RULE="CTY""
    02) Sort table 'Table2'
    03) Inner Join result of '01)' to result of '02)'
          using temporary index
          join expression "QUERY1.COUNTRY=Table2.PAYS"
    On voit bien qu'il se réfère à Table2 dans les 2 cas et non plus à un QUERY1 déjà composé.

    Les moteurs SGBD ont tous leurs spécificités et il faut faire avec.

    Cordialement,
    Détecter les modifications formulaire Cloud storage et ACCESS
    Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
    Visitez mon Blog
    Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie

  5. #5
    Nouveau Candidat au Club
    Femme Profil pro
    Chef projet SAP
    Inscrit en
    Juin 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef projet SAP

    Informations forums :
    Inscription : Juin 2020
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    j'ai simplifié pour isoler le bug mais dans Query 1 je rappatrie aussi d'autres infos d'ou cette query
    et dans query 2 je croise avec d'autres query (notamment d'autres regles de naming si Rule = REG par exemple)

    le bug que j'observe est que

    "Là où il n'y a pas de correspondance il ne met rien, sauf si vous indiquez une valeur, dans ce cas il renvoi cette valeur, puis que l'obligation de table1 le lui ordonne."
    ne marche pas (ou je ne comprends pas la phrase )

    effectivement il ne met rien si la formule de de [zone] dans Query1 est [TABLE1].[COUNTRY] & [TABLE1].[RULE] AS [zone] mais si la formule est [TABLE1].[COUNTRY] & "F0000000" AS [zone] alors il met uniquement la partie texte "F00000000". c'est etrange que le resultat soit different si la formule contient une portion texte ou pas.

    il semble que je doive faire avec!
    merci pour les retours, je vais inclure cette condition dans la formule de Zone et non en critere de filtre pour contourner le pb.

  6. #6
    Membre actif
    Homme Profil pro
    Retraité
    Inscrit en
    Février 2012
    Messages
    284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Bâtiment

    Informations forums :
    Inscription : Février 2012
    Messages : 284
    Points : 284
    Points
    284
    Par défaut
    C'est suivant comment tu mets ta jointure: toutes les requêtes "Oui" donnent le bon résultat
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    SELECT TABLE2.PARTNER, QUERY1.ZOne_name
    FROM QUERY1 INNER JOIN TABLE2 ON QUERY1.COUNTRY = TABLE2.PAYS;  Oui
     
    SELECT TABLE2.PARTNER, QUERY1.ZOne_name
    FROM QUERY1 LEFT JOIN TABLE2 ON QUERY1.COUNTRY = TABLE2.PAYS;  Oui
     
    SELECT TABLE2.PARTNER, QUERY1.ZOne_name
    FROM QUERY1 RIGHT JOIN TABLE2 ON QUERY1.COUNTRY = TABLE2.PAYS;  Non
     
     
    SELECT TABLE2.PARTNER, QUERY1.ZOne_name
    FROM TABLE2 LEFT JOIN QUERY1 ON TABLE2.PAYS = QUERY1.COUNTRY;  Non
     
    SELECT TABLE2.PARTNER, QUERY1.ZOne_name
    FROM TABLE2 INNER JOIN QUERY1 ON TABLE2.PAYS = QUERY1.COUNTRY; Oui
     
    SELECT TABLE2.PARTNER, QUERY1.ZOne_name
    FROM TABLE2 RIGHT JOIN QUERY1 ON TABLE2.PAYS = QUERY1.COUNTRY;  Oui
    Un travail qui plait est à moitié fait.

Discussions similaires

  1. [Processing]Rotation Texte à part
    Par TenshiKira dans le forum Autres
    Réponses: 15
    Dernier message: 26/01/2017, 22h46
  2. Erreur: '-' in expression is not part of the query"
    Par Marc_27 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 03/06/2010, 08h16
  3. Unable to download the artifact from any repository
    Par Methode dans le forum Maven
    Réponses: 3
    Dernier message: 02/02/2009, 14h27
  4. C8 query studio Null value
    Par mhamedbj dans le forum Cognos
    Réponses: 8
    Dernier message: 25/08/2008, 09h56
  5. Could not find a part of the path
    Par Poussy-Puce dans le forum ASP.NET
    Réponses: 5
    Dernier message: 02/02/2007, 19h56

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