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 :

Problème SQL imbriqué


Sujet :

Langage SQL

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

    Informations forums :
    Inscription : Février 2008
    Messages : 12
    Points : 11
    Points
    11
    Par défaut Problème SQL imbriqué
    Bonjour, pour mon petit site amateur j'ai besoin de faire une requête sql imbriquand une autre requête. J'ai fais ca

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT * FROM `ex_mycontest`,`ex_vote` 
    WHERE `ex_mycontest`.`ex_myc_validation` = '1'
    AND `ex_mycontest`.`ex_myc_proprietaire` <> '" . $_SESSION['id'] . "'
    AND `ex_mycontest`.`ex_myc_actif` = '1'
    AND `ex_mycontest`.`ex_myc_datetime` > '" . time() . "'  					
    AND `ex_mycontest`.`ex_myc_multiple` > (SELECT COUNT(*)  FROM `ex_vote` WHERE `ex_vi_contest`='`ex_mycontest`.`ex_myc_id`' AND ex_vi_votant='" . $_SESSION['id'] . "' AND ex_vi_etat ='1' OR ex_vi_etat ='2')
    ORDER BY `ex_mycontest`.`ex_myc_id` DESC 
    LIMIT 20;
    et voila le résultat si je le print
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT * FROM `ex_mycontest`,`ex_vote` 
    WHERE `ex_mycontest`.`ex_myc_validation` = '1' 
    AND `ex_mycontest`.`ex_myc_proprietaire` <> '1' 
    AND `ex_mycontest`.`ex_myc_actif` = '1' 
    AND `ex_mycontest`.`ex_myc_datetime` > '1325789742' 
    AND `ex_mycontest`.`ex_myc_multiple` > (SELECT COUNT(*) FROM `ex_vote` WHERE `ex_vi_contest`='`ex_mycontest`.`ex_myc_id`' AND ex_vi_votant='1' AND ex_vi_etat ='1' OR ex_vi_etat ='2') 
    ORDER BY `ex_mycontest`.`ex_myc_id` DESC 
    LIMIT 20;
    visiblement tout marche sauf '`ex_mycontest`.`ex_myc_id`' ligne 7 ... En mettant en dur une valeur (ex : 10) ma requete s'execute correctement et tout marche hors '`ex_mycontest`.`ex_myc_id`' ne se converti pas en '10'.

    Comment faire pour donner le chiffre dans la deuxieme requête?

    merci de votre aide

  2. #2
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Points : 1 327
    Points
    1 327
    Par défaut
    Bonjour,
    il faut donner un alias à ta table dans la requête ptrincipale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT * FROM `ex_mycontest` C,`ex_vote` 
    WHERE `ex_mycontest`.`ex_myc_validation` = '1'
    AND `ex_mycontest`.`ex_myc_proprietaire` <> '" . $_SESSION['id'] . "'
    AND `ex_mycontest`.`ex_myc_actif` = '1'
    AND `ex_mycontest`.`ex_myc_datetime` > '" . time() . "'  					
    AND `ex_mycontest`.`ex_myc_multiple` > (SELECT COUNT(*)  FROM `ex_vote` WHERE `ex_vi_contest`= C.`ex_myc_id` AND ex_vi_votant='" . $_SESSION['id'] . "' AND ex_vi_etat ='1' OR ex_vi_etat ='2')
    ORDER BY `ex_mycontest`.`ex_myc_id` DESC 
    LIMIT 20;
    Par contre toutes ces quotes sont-elles nécessaires ?
    En théorie on n'a pas à mettre de quotes autour des noms de tables et de champs ... après c'est du mysql je suppose mais est-ce tout de même nécessaire ?

  3. #3
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !
    Ce ne sont pas des vraies quotes (sinon ça passerait pas)... et ça sert à encapsuler les noms d'objets étranges (des espaces, ...)

    Ce n'est pas spécifique à MySQL. Sous Oracle, tu peux passer les noms d'objets entre double quotes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    select * from "DUAL"
     
    D
    -
    X
     
     
    1 row selected.
    Par ailleurs, je suppose que certains générateurs de code doivent te mettre systématiquement des back quotes autour des noms d'objets ? Ou alors c'est une convention douteuse dans certains endroits ?

    PS : et je m'avance peut être un peu, mais il me semble que sous SQL Server tu peux mettre des [] autour des noms d'objets DB.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Points : 1 327
    Points
    1 327
    Par défaut
    Ah ok, en DB2 il me semble aussi qu'on peut utiliser les doubles quotes pour le faire, mais là en l'occurence les noms d'objets sont normaux donc les quotes ne sont pas nécessaires.
    Merci pour l'info.

    Juste petite précision comme j'ai du faire du MySql une seule fois, si SELECT * FROM `ex_mycontest` C ne passe pas essaye SELECT * FROM `ex_mycontest` as C

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Par contre là
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    '`ex_mycontest`.`ex_myc_id`'
    Y a bien un problème de quote

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

    Informations forums :
    Inscription : Février 2008
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    Bonjour, visiblement il falait simplement rajouter le nom de la table dans la seconde requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT * FROM `ex_mycontest` ,`ex_vote` 
     WHERE `ex_mycontest`.`ex_myc_validation` = '1'
     AND `ex_mycontest`.`ex_myc_proprietaire` <> '" . $_SESSION['id'] . "'
     AND `ex_mycontest`.`ex_myc_actif` = '1'
     AND `ex_mycontest`.`ex_myc_datetime` > '" . time() . "'                                         
     AND `ex_mycontest`.`ex_myc_multiple` > (SELECT COUNT(*)  FROM <span style="font-weight: bold">`ex_mycontest`</span> , `ex_vote` WHERE `ex_vi_contest`= `ex_myc_id` AND ex_vi_votant='" . $_SESSION['id'] . "' AND ex_vi_etat ='1' OR ex_vi_etat ='2')
     ORDER BY `ex_mycontest`.`ex_myc_id` DESC 
     LIMIT 20";
    merci et bonne journée

  7. #7
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Points : 1 327
    Points
    1 327
    Par défaut
    On n'a pas plus d'infos sur ce à quoi correspondent tes champs et tes variables PHP mais cette requête ne fait absoluement pas la même chose que la requête de départ.

  8. #8
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    J'ai remarqué aussi que dans ta requête principale la table ex_vote apparait alors que tu ne l'utilises que dans ta sous-requête. Cela doit influencer ton SELECT *, tu devrais l'enlever.

  9. #9
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    C'est une horreur cette requête !

    1) Évite la guerre des étoiles !

    2) Tu mets deux tables dans le FROM mais aucune condition de jointure dans le WHERE. Tu fais donc le produit cartésien des deux tables.
    Est-ce que tu souhaites ?

    Si tu fais une jointure entre les deux tables, apprends à l'écrire selon la syntaxe en vigueur depuis 20 ans !

    Mais comme dit lola06, si la table ex_vote est inutile dans la requête principale, supprime là carrément.

    3) Si les colonnes du WHERE sont de type numérique, comme le suggèrent les valeurs cherchées (sauf la date), inutile d'ajouter des apostrophes !

    4) Plutôt que la fonction time() de PHP, utilise la fonction CURRENT_TIME du langage SQL.

    5) Utilise des alias dès qu'il y a plus d'une table dans une requête ; ça rend la requête plus agréable à lire.

    Voici la requête partiellement nettoyée :
    Code : 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 -- les colonnes nécessaires et pas étoile !
    FROM ex_mycontest c
    INNER JOIN ex_vote v ON -- Condition de jointure !
    WHERE c.ex_myc_validation = '1' -- Colonne numérique ? => Pas d'apostrophes !
    	AND c.ex_myc_proprietaire <> '" . $_SESSION['id'] . "' -- Colonne numérique ? => Pas d'apostrophes !
    	AND c.ex_myc_actif = '1' -- Colonne numérique ? => Pas d'apostrophes !
    	AND c.ex_myc_datetime > CURRENT_TIME
    	AND c.ex_myc_multiple > 
    	(
    		SELECT COUNT(*)  
    		FROM ex_vote 
    		WHERE ex_vi_contest = c.ex_myc_id 
    			AND ex_vi_votant = '" . $_SESSION['id'] . "' -- Colonne numérique ? => Pas d'apostrophes !
    			AND ex_vi_etat = '1' -- Colonne numérique ? => Pas d'apostrophes !
    			OR ex_vi_etat = '2' -- Colonne numérique ? => Pas d'apostrophes !
    	)
    ORDER BY c.ex_myc_id DESC 
    LIMIT 20;

  10. #10
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par pacmann Voir le message
    Ce n'est pas spécifique à MySQL. Sous Oracle, tu peux passer les noms d'objets entre double quotes
    Il me semble que quand on double-quote les objets sous Oracle dans un ordre CREATE, ça a un effet spécifique; en l'occurence, ça fige la case-sensitivity du nom, alors que les noms des objets sont normalement case-insensitive.

    En clair si on fait

    on peut faire

    mais si on fait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE TABLE "theTable"
    tout autre variation de casing de theTable ne sera pas reconnu.

  11. #11
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Pour Oracle je ne sais pas encore mais depuis que j'ai découvert ce piège dans Postgresql, je nomme toutes mes tables et colonnes en minuscules !

Discussions similaires

  1. Problème de requêtes SQL imbriquées
    Par lakel dans le forum Schéma
    Réponses: 4
    Dernier message: 12/01/2012, 14h09
  2. Problème de requêtes SQL imbriquées
    Par leroimarco dans le forum PureBasic
    Réponses: 9
    Dernier message: 14/07/2011, 11h57
  3. [Problème SQL] Sum, Count + requête imbriquée
    Par Lolie11 dans le forum Langage SQL
    Réponses: 7
    Dernier message: 06/01/2009, 18h08
  4. Problème SQL
    Par Florent0001 dans le forum Langage SQL
    Réponses: 8
    Dernier message: 10/11/2004, 17h07
  5. Problèmes SQL
    Par stampe dans le forum Bases de données
    Réponses: 2
    Dernier message: 06/07/2004, 21h02

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