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

PHP & Base de données Discussion :

Probleme sous requete


Sujet :

PHP & Base de données

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 26
    Par défaut Probleme sous requete
    Bonjour,

    Quand je lance la requete ci-dessous depuis une page PHP le résultat n'est pas le bon. Quand je le lance directement dand PHPMYADMIN ca fonctionne. Ca fais trois jour que je cherche une soluton et ne trouve pas.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT c.pseudo, c.titre_concours, c.datelimite, c.remarque, c.url_concours, c.type_concours, c.id_concours,c.datedujour FROM concours c  WHERE  c.datedujour = curdate()  AND c.id_concours Not in (Select ri.id_concours From reponses ri Where ri.id_concours = c.id_concours) AND (c.id_concours, '$login') Not in (Select p.id_concours, p.pseudo From perso p WHERE p.id_concours = c.id_concours and p.pseudo='$login') ORDER BY datelimite");

    Merci.

  2. #2
    Membre Expert

    Homme Profil pro
    Spécialiste progiciel
    Inscrit en
    Février 2010
    Messages
    1 747
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Spécialiste progiciel
    Secteur : Service public

    Informations forums :
    Inscription : Février 2010
    Messages : 1 747
    Par défaut
    BOnjour,

    Est-ce qu'il ne faut pas définir les alias des tables en MySQL avec AS ?

    Je ne suis pas sur mais il se peut que ce soit ton erreur.
    Il me semble avoir eu le cas avec une version assez ancienne de MySQL.
    Il te manque aussi pour l'orderby le nom de la table devant le champs comme préfixe.
    Peut être il y a un problème de casse (un champ en majuscule quelque part dans ta base).
    En espérant t'avoir aidé, tiens nous au courant

    Cordialement,
    Christophe

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 26
    Par défaut
    J'ai essayer ta solution mais ca ne fonctionne pas. J'ai même mis la valeur de la variable directement dans la requête, même résultat.

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Quel resultat obtiens-tu quand tu executes ta requêtes via PHP ?
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 26
    Par défaut
    L'enregistrement de la table perso ne devrait pas s'afficher car le
    ID est le même ainsi que le pseudo qui est égal à $login(fost).

    Table concours:

    ID
    34 sddss sdsd http://www.ebay.ca sdsd sds 2010-03-25 2010-03-19 sdsd

    Table perso :

    ID Pseudo
    34 fost 2010-03-17 2010-03-26 sdsd http://www.ebay.ca


    J'ai fais un explain dans Phpmyadmin, il semble que le 2ieme WHERE est en problème. voici le résultat :


    3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE

  6. #6
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Salut

    Comme ça, au feeling, j'ai l'impression que les sous requêtes ne seraient pas si indispensables.

    Est ce que cette requête retourne les lignes attendues ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $sql = "SELECT c.pseudo, ... etc ...
    FROM concours c
    JOIN reponses ri ON ri.id_concours != c.id_concours
    JOIN perso p ON p.id_concours = c.id_concours
    WHERE c.datedujour = curdate()
    AND p.pseudo = '$login'
    ORDER BY datelimite";
    Ce qui m'intrigue le plus, c'est ceci : AND (c.id_concours, '$login') NOT IN (SELECT ... )
    Qu'est ce que cela doit faire, récupérer ?
    La syntaxe est elle correcte d'ailleurs ? (il me semble que non)

    Sans garantie

  7. #7
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 506
    Par défaut
    Je confirme ce que dit RunCodePHP :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    AND (c.id_concours, '$login')
    Ceci ne correspond à rien, je suis d'ailleurs étonné que cela passe dans un IDE de requête SQL.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 26
    Par défaut
    Bonjour,

    Je vais essayer d'être plus précis.

    J'ai trois tables (concours - reponses- perso). Si les données de la table concours se retrouve dans la table reponse on ne récupère pas les données et si les données et le $login se retrouvent dans la table perso on ne rupère rien -> Not in (Select p.id_concours, p.pseudo From perso as p WHERE p.id_concours = c.id_concours and p.pseudo='fost')


    Exemple :
    J'ai un site Web qui permet aux gens d'aller s'inscrire à des concours. Quand un membre s'inscrit à un concours, je récupère les données du concours et les insèrent dans une table (perso). Quand le membre revient sur le site, il ne voit plus ce concours car il s'y est déjà inscrit d'ou le pourquoi de comparer le id_concours et le pseudo de la table perso.

    En espèrant avoir été plus clair.

  9. #9
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Alors peut être faudrait il modifier cette condition :
    AND p.pseudo = '$login'
    par :
    AND p.pseudo != '$login'


    Concernant la table "response", à mon avis elle ne sert pas à grand chose dans ce cas là, la requête devrait se simplifier.
    Si je comprends bien, c'est la table "perso" qui contient avant tout l'ID du concourt et le pseudo de la personne.
    Donc que la table "response" a une ligne ou pas de cette personne ne changerait rien.
    C'est la table "perso" l'élément le plus important, non ?

    En somme, on récupère les concours ou la personne ne s'est pas inscrite.
    C'est ça ou pas ?


    Si il faut récupérer quand même les concours où il n'y pas eus de réponses (table response) malgré que la personne soit inscrite (table perso), c'est légèrement différent.
    Faudrait préciser.


    Je me demande si cette requête ne serait pas suffisante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $sql = "SELECT c.pseudo, ... etc ...
    FROM concours c
    JOIN perso p ON p.id_concours = c.id_concours
    WHERE p.pseudo != '$login'
    AND c.datedujour = curdate()
    ORDER BY datelimite";
    Si c'est trop restrictif, alors une sous requête effectivement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $sql = "SELECT c.pseudo, ... etc ...
    FROM concours c
    WHERE c.id_concours NOT IN (SELECT p.id_concours FROM perso p WHERE p.perso = '$login')
    AND c.datedujour = curdate()
    ORDER BY datelimite";
    En essayant ces 2 requêtes, et si ça fonctionne pas correctement, qu'est ce qui est récupérer de trop ?
    Ou bien, quelles sont les lignes manquantes ?

    Question comme ça. Comment ce fait il que la vérification se fasse sur le pseudo ?
    Une personne n'aurait elle pas un ID ?

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 26
    Par défaut
    SELECT c.pseudo, c.titre_concours, c.datelimite, c.remarque, c.url_concours, c.type_concours, c.id_concours,c.datedujour FROM concours as c WHERE


    c.datedujour = curdate() // Vérifie si égal à date du jour



    AND c.id_concours Not in (Select ri.id_concours From reponses as ri Where ri.id_concours = c.id_concours) // On vérifie si le concours n'est pas dans la table réponse -> Si vrai, on ne récupère pas le concours.



    AND (c.id_concours, 'fost') Not in (Select perso.id_concours, perso.pseudo From perso WHERE perso.id_concours = c.id_concours and perso.pseudo='fost') // Si le concours existe et que le pseudo est égal à la personne en session -> on ne récupère pas ce concours.

    *** Plusieurs personnes peuvent avoir le même concours

    Il y a une erreur sur le deuxième 'Where'. Voir fichier inclus.

    Merci pour votre aide.
    Images attachées Images attachées  

  11. #11
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Je ne comprends pas ta démarche ci-dessus, car tu ne fais que redire, et même refaire les choses qu'au tout début.


    Tu demande une aide pour une requête, on te propose des requêtes, mais apparemment tu ne fais pas d'essai, du moins, pas l'ombre d'un retour.
    Si c'est pas bon, ok, mais encore faut il le dire, non ?

    Je n'ai pas tes tables, ni tes données, impossible pour moi de savoir si c'est bon ou pas, et éventuellement corriger au besoin.
    Je ne peux pas faire les essais à ta place en tout cas.


    De plus, on te dis qu'il y a une partie de ta requête qui serait syntaxiquement fausse.
    Du coup, il est fort probable qu'un "explain" aboutira sur une analyse fausse.
    Un "explain" est efficace uniquement si la requête et que les structures des tables sont bonnes. L'analyse va fournir de éventuelles optimisations à effectuer.
    Encore que, faut savoir bien interpréter les résultats, ça peut être la "cata" si on effectue les suggestions les yeux fermés.

    Dans ton cas, je ne vois pas ce que pourrait apporter un "explain", car il faut au moins que la requête retourne exactement ce qu'il faut.
    C'est après qu'on voit s'il y a moyen d'optimiser.
    Ceci dit, je peux me tromper.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 26
    Par défaut
    Désolé, j'aurais effectivement dû répondre aux personnes qui m'ont proposé des solutions. Mais sois certain que je les ai essayées et elles n'ont pas donné les résultats attendues. Je viens de m'apercevoir que j'ai fais une erreur. Je faisais ma requête sur trois tables alors que j'avais seulement besoin de deux tables (perso et concours).

    Donc :

    SELECT c.pseudo, c.titre_concours, c.datelimite, c.remarque, c.url_concours, c.type_concours, c.id_concours,c.datedujour FROM concours c
    WHERE c.datedujour = curdate() AND (c.id_concours, 'fost')
    Not in (Select perso.id_concours, perso.pseudo From perso
    WHERE perso.id_concours = c.id_concours and perso.pseudo='fost')
    ORDER BY datelimite

    Cette requête fonctionne lancé depuis phpmyadmin.

    Elle ne fonctionne pas lancé depuis le web. Elle me retourne les enregistrements avec 'fost'.

    J'inclus le résultat des deux requetes. dans la requete Web,Le id 29 ne devrait pas être là.
    Merci.
    Images attachées Images attachées   

  13. #13
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    C'est dommage, tu as mis 2 captures d'écrans, très bien, mais il aurait été pas mal d'avoir le contenu de la table "perso".

    Je viens de m'apercevoir que j'ai fais une erreur. Je faisais ma requête sur trois tables alors que j'avais seulement besoin de deux tables (perso et concours).
    C'est ce que je disais dans un post plus haut.

    SELECT c.pseudo, c.titre_concours, c.datelimite, c.remarque, c.url_concours, c.type_concours, c.id_concours,c.datedujour FROM concours c
    WHERE c.datedujour = curdate() AND (c.id_concours, 'fost')
    Not in (Select perso.id_concours, perso.pseudo From perso
    WHERE perso.id_concours = c.id_concours and perso.pseudo='fost')
    ORDER BY datelimite

    Cette requête fonctionne lancé depuis phpmyadmin.
    Et bien je n'est pas d'explication pourquoi elle fonctionne sur PhpMyAdmin, mais on est 2 à te dire quelle est syntaxique fausse.
    Cette partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AND (c.id_concours, 'fost') 
    Not in (Select perso.id_concours, perso.pseudo ...)
    Elle serait mieux comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AND c.id_concours 
    Not in (Select perso.id_concours FROM ...)

    Si ça ne tennais qu'à moi, je n'insisterais pas sur cette requête.
    Puis ton besoin ce résume à récupérer tout les concours SAUF ceux de la personne, les autres quoi.

    La requête serait du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT c.pseudo ... etc ...
    FROM concours c
    JOIN perso p ON p.id_concours = c.id_concours
    WHERE p.pseudo != 'test'
    AND c.datedujour = curdate()
    ORDER BY c.datelimite
    Cependant, il y a des trucs pas clairs dans la conception de tout ça.
    Je ne vois pas pourquoi il y a le champ (et les données) "pseudo" dans la table "concours".
    La table "concours" devrait contenir des concours, et uniquement des concours, non ?

    C'est la table "perso" qui elle contient les couples "id_concours / pseudo", les concours où la personne c'est inscrite.

    Aussi, utiliser un champ de type "varchar" (pseudo) pour lier 2 tables, pourquoi pas, mais un ID aurait plus approprié à mon sens.

    Autre truc encore.
    Je n'arrive pas à comprendre le but ou l'intérêt du champ "datedujour" de la table "concours" ? Il sert à quoi ?

    Puis, par convention, on place les clés primaires en tout 1er.
    Donc le champ "id_concours" de la table "concours" est mal placé, c'est quelque peu déroutant.
    Ici, c'est juste une petite remarque

  14. #14
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 506
    Par défaut
    Et puis pour RunCodePhp se repose un peu , et parce que tu tiens absolument à ta requête malgré l'optimisation qu'il t'es proposé, ceci correspondra (normalement à tes attentes).

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT c.pseudo, c.titre_concours, c.datelimite, c.remarque, c.url_concours, c.type_concours, c.id_concours,c.datedujour FROM concours c
    WHERE c.datedujour = curdate() AND c.id_concours Not in (Select perso.id_concours From perso
    WHERE  perso.pseudo='fost')
    ORDER BY datelimite

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 26
    Par défaut
    CA FONCTIONNE!!!!!

    Merci beaucoup les gars de m'avoir aider à régler cet épineux problème(pas pour vous). Je vais essayer de répondre à RunCode Php. La table concours a été créer avec le peu de connaissances que j'ai de SQL.


    Je ne vois pas pourquoi il y a le champ (et les données) "pseudo" dans la table "concours".
    La table "concours" devrait contenir des concours, et uniquement des concours, non ?


    Le pseudo est le nom du membre qui a trouvé le concours. Les informations du concours sont entrées à travers un formulaire et insérer dans la table concours.

    C'est la table "perso" qui elle contient les couples "id_concours / pseudo", les concours où la personne c'est inscrite.

    La table perso contient les informations des inscriptions aux concours fait par les membres. Quand un membre s'inscrit à un concours, je récupère les infos que j'ai besoin et les insère dans cette table ceci a pour but d'éviter que le concours s'affiche de nouveau quand le membre s'y est déjà inscrit, je dois comparer le id_concours et le pseudo car si je récupère seulement le id_concours, le concours ne s'affichera pas pour les autres membres.


    Aussi, utiliser un champ de type "varchar" (pseudo) pour lier 2 tables, pourquoi pas, mais un ID aurait plus approprié à mon sens.

    Il me semble que c'est le id-concours qui lie les deux tables.


    Autre truc encore.
    Je n'arrive pas à comprendre le but ou l'intérêt du champ "datedujour" de la table "concours" ? Il sert à quoi ?


    LA date du jour est la date ou le membre à inscrit le concours sur mon site, car comme il a plus de 400 concours sur le site, je les affichent par date.


    Puis, par convention, on place les clés primaires en tout 1er.
    Donc le champ "id_concours" de la table "concours" est mal placé, c'est quelque peu déroutant.
    Ici, c'est juste une petite remarque


    N'est-il pas placé en premier? là je ne comprends pas.



    Une dernière question :

    Quelle est la meilleur facon de coder une requête sur deux tables ou plus :

    Par une jointure ou une sous-requête?

    Merci encore.
    Images attachées Images attachées   

  16. #16
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Ok.
    Je ne fais que poser des questions, non pas pour savoir, je n'ai aucun rapport avec ton projet, mais pour toi, au cas où tu verrais un truc douteux


    Pour la table "perso", je ne vois pas de clé primaire. Il en faut une.
    Puis comme je l'ai dis plus haut, l'élément qui désigne une personne est un varchar "pseudo".

    Ca m'amène une autre question.
    Tu devrais avoir une table avec la listes des personnes non ?
    Si c'est le cas, cette table devrait avoir une clé primaire, un ID (genre user_id), donc chaque personne peut être récupéré/désigné par cet ID.
    Du coup, au lieu d'avoir un champ "pseudo" dans la table "perso", il serait mieux d'avoir ce même champ (user_id) et comme valeur leur ID.

    Toujours pour cette table "perso", qui donc devrait avoir une clé primaire.
    Comme c'est une table qui stock les concours des personnes, il peu avoir 2 façons de créer cette clé primaire.
    - Si une personne ne peux pas (ou ne doit pas même) s'inscrire 2 fois à un même concours, alors la clé primaire serait double :
    PRIMARY KEY (id_concours, id_user)
    - Si une personne peut s'inscrire (au moins) 2 fois à un même concours, alors il faudrait un nouveau champ, des valeurs uniques par lignes (en auto_incremente par exemple).


    Quelle est la meilleur facon de coder une requête sur deux tables ou plus :
    Par une jointure ou une sous-requête?
    Théoriquement une jointure est plus rapide.
    Cependant, pour que ça se remarque, faut que la requête parcourt un sacré gros paquet de données, ou alors qu'on fasse énormément de requêtes, ou de traitement pour pousser l'optimisation à ce point.
    Mais si c'est pas utile, ça sert à rien de faire une sous requête malgré tout.

    Par conte, il y a des cas ou une sous requête est indispensable, impossible de faire la même chose en jointure en 1 seule requête.

    Mais dans ton cas une sous requête n'a pas vraiment d'utilité.
    D'ailleurs, la requête que t'as proposé MaitrePylos est la même que celle que j'avais fait plus haut. Il y en avait 2 : Une avec jointure, l'autre en sous requête.

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 26
    Par défaut
    Merci beaucoup pour ces conseils. J'en prends bonne note.

    Et encore un gros MERCI pour avoir pris le temps de m'aider.


    A+

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/12/2005, 11h53
  2. Probleme de sous requete DEBUTANT
    Par nashouille dans le forum Langage SQL
    Réponses: 4
    Dernier message: 30/09/2005, 12h47
  3. probleme avec requete et sous-requete...
    Par birkoss dans le forum Langage SQL
    Réponses: 5
    Dernier message: 17/08/2005, 22h26
  4. probleme de requete (de sous requetes ?)
    Par menoce dans le forum Requêtes
    Réponses: 6
    Dernier message: 08/07/2005, 16h23
  5. probleme de sous requete
    Par JD_Lyon dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 09/04/2004, 23h18

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