Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 19/06/2011, 17h52   #1
Invité de passage
 
Inscription : novembre 2006
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 19
Points : 3
Points : 3
Par défaut Requête imbriquée ne fonctionnant pas

Bonjour,

pour mon forum de discussion, sur mon site, je voudrais faire apparaître les sujets qui traient d'un objet particulier (qu'on peut rechercher par la fonction recherche). En l’occurrence, il s'agit de trouver les discussions sur l'amandier, si on va sur la page de qui parle de cet arbre.
en local cette requête ci-dessous marche bien, mais elle ne fonctionne pas sur le serveur (1 et 1) :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
SELECT topic_title,topic_id 
FROM phpbb_topics 
WHERE topic_id IN (
  SELECT DISTINCT topic_id 
  FROM phpbb_posts 
  WHERE post_id IN (
    SELECT post_id 
    FROM phpbb_posts_text 
    WHERE post_text LIKE '$match_word'
  )
) 
LIMIT 0,10
j'ai posé la question sur le forum que j'utilise mais personne n'a répondu c'est pourquoi je tente ma chance ici.
en attendant, j'ai mis une autre forme plus simple de requête, visible par ex sur cette page :
http://www.lesarbres.fr/amandier.html
c'est à "Voir les sujets du forum sur cet arbre"

merci pour votre aide
lesarbres est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/06/2011, 18h02   #2
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 954
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 954
Points : 17 774
Points : 17 774
LIMIT n'existe pas en SQL, ni dans SQL Server. C'est un truc spécifique à MySQL.
Si tu veut retourner un ensemble précis il faut utiliser les fonctions de ranking de la norme SQL comme ROW_NUMBER.

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/06/2011, 21h43   #3
Invité de passage
 
Inscription : novembre 2006
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 19
Points : 3
Points : 3
désolé, je n'ai pas été clair mais c'est du Mysql
que j'utilise sur un site en php
mais si le reste des instruction est commun au sql je veux bien avoir une aide sur le reste, sans parler du limit
je précise que ma requête marche sur mon serveur local (apache), mais ne marche pas sur le serveur distant.
je suppose qu'il faut décomposer la requête avec des résultats temporaires, mais je ne sais pas le faire.
lesarbres est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 00h20   #4
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 008
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 11 008
Points : 18 279
Points : 18 279
Envoyer un message via MSN à CinePhil
Toi, tu as besoin d'un cours sur les jointures !

Citation:
en local cette requête ci-dessous marche bien, mais elle ne fonctionne pas sur le serveur (1 et 1)
En quoi ne fonctionne t-elle pas ? Erreur ? Pas le bon résultat ? Pas de résultat du tout ?
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 09h03   #5
ced
Rédacteur/Modérateur

 
Avatar de ced
 
Homme Cédric Duprez
Inscription : avril 2002
Messages : 3 823
Détails du profil
Informations personnelles :
Nom : Homme Cédric Duprez
Âge : 36
Localisation : France, Loiret (Centre)

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : avril 2002
Messages : 3 823
Points : 6 437
Points : 6 437
Citation:
Envoyé par SQLpro Voir le message
LIMIT n'existe pas en SQL, ni dans SQL Server. C'est un truc spécifique à MySQL.
Pas seulement MySQL... PostgreSQL utilise aussi la clause LIMIT, par exemple.
__________________
Rédacteur / Modérateur SGBD
Mes tutoriels et la FAQ MySQL

----------------------------------------------------
Pensez aux balises code et au tag
Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
ced est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 10h23   #6
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 954
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 954
Points : 17 774
Points : 17 774
Désolé, je croyais être sur le forum SQL !!!!

LIMIT existe effectivement sous MySQL, mais pas dans le langage SQL !

Et cela fait partit des "trucs" non relationnels qui relèvent quelques pièges....

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2011, 10h34   #7
Invité de passage
 
Inscription : novembre 2006
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 19
Points : 3
Points : 3
Citation:
Envoyé par CinePhil Voir le message
Toi, tu as besoin d'un cours sur les jointures !


En quoi ne fonctionne t-elle pas ? Erreur ? Pas le bon résultat ? Pas de résultat du tout ?
oui, il faut que j'apprenne les jointures;
la requête donne bien un résultat en local mais sur le serveur distant, le résultat est= 0
je suppose qu'il faut décomposer en 3 étapes et 3 requêtes et stocker les résultats intermédiaires temporaires.

le schéma est le suivant :

Code :
1
2
3
4
5
6
7
base	                                extraire	    cdt
 
phpbb_posts_text (texte des messages)	post_id	             post_text LIKE '$match_word'
 
phpbb_posts (numéro de messages)	topic_id	       les post_id précédemment sélectionnés
 
phpbb_topics (n° et titres de sujets)	topic_title,topic_id	les topic_id précédemment sélectionnés
J'ai tenté une autre solution mais qui ne marche pas car je ne sais pas bien le faire :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//je crée une TABLE qui contient le résultat de la requête
        $query = "CREATE TEMPORARY TABLE tmp_table_posts AS SELECT post_id 
    		FROM phpbb_posts_text 
    		WHERE post_text LIKE '$match_word'  LIMIT 0, ".$nb_derniers_commentaires;
        mysql_query($query, $connection);
 
 
//je crée une seconde TABLE qui contient le résultat de la requête
        $query_2 = "CREATE TEMPORARY TABLE tmp_table_topic AS 
		SELECT DISTINCT topic_id 
  		FROM phpbb_posts 
  		WHERE phpbb_posts.post_id=tmp_table_posts.post_id";
        mysql_query($query_2, $connection);
 
//DROP TABLE  tmp_table_posts ;
//DROP TABLE  tmp_table_topic ;
 
 
		$sql = mysql_query("SELECT topic_title,topic_id 
		FROM phpbb_topics 
		WHERE phpbb_topics.topic_id=tmp_table_topic.topic_id", $connection);
 
	$nbResults = mysql_num_rows($sql);
merci pour votre aide
lesarbres est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 21h06   #8
Invité de passage
 
Inscription : novembre 2006
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 19
Points : 3
Points : 3
Bonjour

je cherche toujours , sur une autre voie cette fois : j'ai fait des jointures sur une partie de requête :
Code :
1
2
3
4
$sql = mysql_query("SELECT topic_title,topic_id FROM phpbb_topics WHERE topic_id IN (SELECT DISTINCT phpbb_posts.topic_id 
  FROM phpbb_posts,phpbb_posts_text  
  WHERE phpbb_posts.post_id =phpbb_posts_text.post_id 
    AND phpbb_posts_text.post_text LIKE '$match_word') LIMIT 0, ".$nb_derniers_commentaires, $connection);
même résultat : ça marche en local, apache, mais pas sur le serveur distant qui héberge mon site
à moins que ce dysfonctionnement ne vienne du serveur (1&1) qui ne tolère pas les requêtes imbriquées
donc merci aux aides, si quelqu’un a une idée
lesarbres est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 00h13   #9
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 008
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 11 008
Points : 18 279
Points : 18 279
Envoyer un message via MSN à CinePhil
Avec des jointures propres, ça devrait donner ça :
Code :
1
2
3
4
5
6
SELECT t.topic_title, t.topic_id
FROM phpbb_topics t
INNER JOIN phpbb_posts p ON p.topic_id = t.topic_id
  INNER JOIN phpbb_posts_text x ON x.post_id = p.post_id
WHERE x.post_text LIKE '%$match_word%'
LIMIT 0,10
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/06/2011, 23h02   #10
Invité de passage
 
Inscription : novembre 2006
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 19
Points : 3
Points : 3
Merci beaucoup cinePhil

j'ai juste rajouté DISTINCT
Code :
1
2
3
4
5
6
SELECT DISTINCT t.topic_title, t.topic_id
FROM phpbb_topics t
INNER JOIN phpbb_posts p ON p.topic_id = t.topic_id
  INNER JOIN phpbb_posts_text x ON x.post_id = p.post_id
WHERE x.post_text LIKE '%$match_word%'
LIMIT 0,10
et ça marche. Avec "distinct", j'affiche un seul titre de topic qui contient plusieurs posts de réponses contenant chacun le mot recherché
(je n'avais pas mis le '%' de%match_word% car il y est dans le match_word ; ça vient de phpbb)
le résultat est sur cet exemple
http://www.lesarbres.fr/amandier.html ("Voir les sujets du forum sur cet arbre")

Maintenant je vais potasser l'instruction JOIN que je ne connaissais pas, pour comprendre.
encore merci
lesarbres est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/06/2011, 23h34   #11
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
DISTINCT associé à LIMIT ne me semble pas forcément le meilleur choix.

L'idée derrière LIMIT est de ramener le plus rapidement possible les X premières lignes, mais DISTINCT à l'inverse nécessite de comparer toutes les lignes de la requête pour retirer les doublons du résultat.

Par contre LIMIT nécessite l'utilisation d'ORDER BY, sinon plusieurs exécutions de la requête peuvent ramener des résultats différents.
Peut être que cette requête sera mieux niveau perf (si elle correspond toujours niveau résultat), en tout cas il faut utiliser le ORDER BY :
Code :
1
2
3
4
5
6
7
8
9
SELECT t.topic_title, t.topic_id
  FROM phpbb_topics t
 WHERE EXISTS (SELECT 1 
                 FROM phpbb_posts p
                 JOIN phpbb_posts_text x ON x.post_id = p.post_id
                WHERE p.topic_id = t.topic_id
                  AND x.post_text LIKE '%$match_word%')
 ORDER BY t.topic_id
 LIMIT 0,10
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/06/2011, 23h34   #12
Invité de passage
 
Inscription : novembre 2006
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 19
Points : 3
Points : 3
bonjour skuatamad,
j'ai complété avec ORDER et DESC
ta requête marche en local et pas sur le serveur de 1&1, du coup je suis resté sur l'autre solution.
ou bien je pourrais enlever le LIMIT et n'afficher que les 10 premiers résultats, mais je n'ai pas réussi à le faire (qchose du genre $i=1 ; et $i+; mais je n'ai pas su où mettre le condition $i<10)
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        while ( $enr = mysql_fetch_array($sql) )
                {
                $titre        = $enr[0];
                $topic_id        = $enr[1];
 
$change_space = "-";
$url_title = $titre;
$url_title = strtolower($url_title);
$url_title = strtr($url_title,'áâàäeêéèëíîìïóôòöúûùüýçñ','aaaaeeeeeiiiioooouuuuycn');
$url_title = preg_replace("/(&gt;|&lt;|&amp;)/",$change_space,$url_title);
$url_title = preg_replace("/[^a-z0-9_\-]/",$change_space,$url_title);
$url_title = preg_replace("/[$change_space]+/",$change_space,$url_title);
($url_title{0} == $change_space ? $url_title = substr($url_title,1) : '' );
($url_title{strlen($url_title)-1} == $change_space ? $url_title = substr($url_title,0, strlen($url_title)-1) : '' );
 
              echo '<li><a href="question/'.$url_title.'-sujet'.$topic_id.'-'.$search_keywords.'.html">'.$titre.'</a></li> ';
			  }
lesarbres est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/06/2011, 01h37   #13
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Citation:
ou bien je pourrais enlever le LIMIT et n'afficher que les 10 premiers résultats,
Non non surtout pas, c'est à MySql de limiter le nombre de résultat afin de na pas encombrer inutilement le réseau. Enfin tout dépend si tu n'as que 30 lignes en tout évidemment là ça passe
Citation:
ta requête marche en local et pas sur le serveur de 1&1
Y a t il un message d'erreur ?
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/06/2011, 06h14   #14
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
SAluton,
La version de MySQL chez 1&1 supporte-t-elle les sub-select ?
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/06/2011, 19h56   #15
Invité de passage
 
Inscription : novembre 2006
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 19
Points : 3
Points : 3
bonjour,
je ne sais pas si 1&1& supporte les subselect
et pour répondre à skuatamad, il n y a pas de message d'erreur mais aucun affichage. Comment puis-je récupérer l'erreur ?
lesarbres est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/06/2011, 22h58   #16
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Citation:
Comment puis-je récupérer l'erreur ?
Aucune idée, normalement elle s'affiche point barre... Quelle est la version de MySql ?
Code :
1
2
3
4
5
6
7
mysql> SELECT version();
+-----------+
| version() |
+-----------+
| 5.1.56    |
+-----------+
1 row IN SET (0.00 sec)
Comment executes tu la requêtes ?
Via le prompt mysql ? via phpmyadmin ? ou via ton appli ?
Si c'est via l'appli il est probable que 1&1 n'affiche aucun message d'erreur...c'est une prod après tout. Mais peut être que via phpmyadmin tu pourrais avoir le message.
Citation:
il n y a pas de message d'erreur mais aucun affichage.
Tu veux dire écran blanc ?
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/06/2011, 23h18   #17
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
As tu consaté en local un réel gain de perf ? parce que sinon rien ne sert de se prendre la tête...l'élément important de mon post était qu'il faut utiliser ORDER BY avec LIMIT.

Sinon tu sembles faire une requête de type recherche dans le forum, as tu envisagé un index FULL-TEXT avec MATCH ?
Plutôt que de trier sur le topic_id, tu pourrais bénéficier d'un poids (la pertinence du résultat)

La requête pourrait être quelque chose comme :
Code :
1
2
3
4
5
6
7
8
SELECT t.topic_title, t.topic_id, sum(MATCH (x.post_text) AGAINST ('$match_word')) AS sum_poids
  FROM phpbb_topics t
  JOIN phpbb_posts p ON p.topic_id = t.topic_id
  JOIN phpbb_posts_text x ON x.post_id = p.post_id
 WHERE MATCH (x.post_text) AGAINST ('$match_word')
 GROUP BY t.topic_title, t.topic_id
 ORDER BY sum(MATCH (x.post_text) AGAINST ('$match_word')) DESC
 LIMIT 0,10
J'utilise la somme juste comme ça, mais le max peut mieux te convenir, en tout cas le DISTINCT ne serait plus suffisant.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2011, 11h23   #18
Invité de passage
 
Inscription : novembre 2006
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 19
Points : 3
Points : 3
je suis allé sur phpmyadmin et j'ai mis la requête que tu m'as donnée :
le résultat est :
version()
4.0.27-max-log

en prod, sur mon site exécuté par le serveur, je n'ai pas de message d’erreur et aucun affichage de résultat de la requête.
lesarbres est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2011, 11h31   #19
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Je crois que MySQL ne supporte les sub-select qu'à partir de la version 4.1
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2011, 11h39   #20
Invité de passage
 
Inscription : novembre 2006
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 19
Points : 3
Points : 3
d'accord, cela expliquerait que 1&1 ne fasse pas les subselect ;
en tout cas merci pour cette discussion,
j'ai appris les jointure et je viens de transformer d'autres requêtes.
Dommage que depuis 10 ans je m’embêtais sans cela (je recopiais dans mes tables, par ex de photos d'arbres - où il y a + de 3.000 lignes - , le nom français, le nom anglais, le nom latin, les fiches descriptives dans les 2 langues alors que j’ai aussi une table qui a les correspondances de noms et fiches).

je vais regarder la solution avec MATCH, mais telle quelle ta proposition de requête donne une erreur. je vais essayer d’approfondir le full-text, histoire d'apprendre de nouvelles fonctions.
lesarbres est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h29.


 
 
 
 
Partenaires

Hébergement Web