Problème de requêtes imbriquées

Résolu
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 - 17 mars 2009 à 19:48
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 - 8 avril 2009 à 23:14
Bonjour,

Malgré plusieurs heures de recherche, je ne trouve pas comment faire fonctionner cette requête mysql...

SELECT tel.tel_tel, tel.type_tel, adresse.nom_adresse, adresse.ville_adresse

FROM tel,adresse WHERE (tel.id_contact OR adresse.id_contact) IN

(SELECT contact.id_contact,contact.nom_contact, contact.prenom_contact

FROM contact where nom_contact LIKE "%'.$_POST['nom'].'%" OR prenom_contact like "%'.$_POST['nom'].'%")

L'erreur est la suivante : Warning : Operand should contain 1 column(s)
Je comprend le message d'erreur mais j'ai aussi essayer une jointure entre la table adresse et la table tel, rien y fait... Je me rend compte de graves lacunes en SQL...

J'ai essayé plein de combinaisons... sans résultat.. à part d'autres messages d'erreur...

Les tables : une table contact, avec une clé primaire id_contact
(et un champs nom etc..), une table adresse avec un champ id_contact
(pour une clé externe et un champ ville etc..) un contact pouvant avoir
plusieurs adresse et une table tel avec également un champ id_contact
(pour une clé externe et un champs type genre domicile etc...), un
contact pouvant avoir plusieurs téléphones, adresses...

Le but étant de récupérer dans un tableau toutes ces informations
sans avoir de "doublons" dans ce tableau (pas autant de ligne pour un
contact que de téléphone par ex.)
J'espère avoir été sufisement clair...

Merci pour vos lumières, là, j'y vois plus rien.

20 réponses

aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
8 avril 2009 à 10:47
salut

un peu tard pour repondre peut, mais on ne sait jamais, et pis ca pourra servir a quelqu'un d'autre

maintenant que j'ai compris, je dirai que le plus simple pour toi est de recuperer toutes les données en SQL (avec tes eventuels contacts en double), en triant par exemple sur les ID de contact, et de faire un traitement derriere en php pour obtenir le tableau que tu veux :
SI (IDContact == IDContactPrédent)
ALORS (Ajouter NumeroTel au Dernier contact du tableau)
SINON (Ajouter Nouveau contact dans le tableau)
3
crn_c21 Messages postés 302 Date d'inscription samedi 24 janvier 2004 Statut Membre Dernière intervention 4 février 2011
19 mars 2009 à 15:16
L'erreur est "normale", tu demande que idcontact soit dans un résultat de requete avec idcontact, nom_contact et prenom_contact!!

WHERE (tel.id_contact OR adresse.id_contact) IN
(SELECT contact.id_contact
FROM contact where nom_contact LIKE "%'.$_POST['nom'].'%" OR prenom_contact like "%'.$_POST['nom'].'%")
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
19 mars 2009 à 15:40
Merci de me répondre!
Mais le problème est que j'ai besoin que ressorte aussi nom_contact & prenom_contact...
Le tout étant d'éviter de faire des requêtes dans une boucle exploitant ma première requête (pour les nom_contact notamment...)
J'espère être clair...
Depuis, on m'a dit que ce n'était pas possible... tout simplement...
Et du coup, je m'oriente sue une requête du genre :
SELECT contact.id_contact, contact.nom_contact,contact.prenom_contact,contact.anniversaire_contact,
tel.tel_tel, tel.type_tel, addresse.ville_adresse
FROM contact ctc
LEFT JOIN tel tels ON tel.contact_id = ctc.contact_id
LEFT JOIN adresse addr ON addr.contact_id = ctc.contact_id
WHERE contact.nom_contact LIKE \'%'.$_POST['nom'].'%\' OR contact.nom_contact LIKE \'%'.$_POST['prenom'].'%\';

et de ranger ce résultat dans un tableau bien indexé pour ne pas avoir autant de ligne nom_contact que de tel par ex...

Un avis?
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
19 mars 2009 à 16:19
J'en profite que le post est ouvert...

De mieux en mieux!

SELECT contact.id_contact, contact.nom_contact,contact.prenom_contact,contact.anniversaire_contact,
tel.tel_tel, tel.type_tel, addresse.ville_adresse
FROM contact ctc
LEFT JOIN tel tels ON tel.id_contact = ctc.id_contact
LEFT JOIN adresse addr ON addr.id_contact = ctc.id_contact
WHERE contact.nom_contact LIKE \'%'.$_POST['nom'].'%\' OR contact.nom_contact LIKE \'%'.$_POST['prenom'].'%\';

me donne, je site:

Unknown column 'contact.id_contact' in 'field list'...

Alors que id_contact existe bien...

Je jure pourtant solennellement que je n'ai jamais parlé de MySQL en mal...
Pourquoi tant de haine?... o_O
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
crn_c21 Messages postés 302 Date d'inscription samedi 24 janvier 2004 Statut Membre Dernière intervention 4 février 2011
19 mars 2009 à 20:17
L'erreur est toujours normale lol!!

Contact.Id_Contact n'existe pas!!

Normal tu as dis que contact s'appelait ctc!!

Donc ctc.id_contact lui existe !!

Existe-t-il un lien entre le Id_COntact de tel et le Id_Contact de Adresse?

Autre question tu desire sortir le nom et prénom contact; mais si ce contact à plusieurs Tel ou pkusieurs adresse tu veux afficher quoi?
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
19 mars 2009 à 20:27
Bonsoir, ma requête à bougé depuis...
J'attends que tout fonctionne pour poster ma solution...

Voici ou j'en suis:

SELECT contact.id_contact, contact.nom_contact, contact.prenom_contact, contact.anniversaire_contact,
tel.tel_tel, tel.type_tel, adresse.nom_adresse, adresse.ville_adresse FROM contact
LEFT JOIN tel ON (tel.id_contact = contact.id_contact)
LEFT JOIN adresse ON (adresse.id_contact = contact.id_contact)
WHERE contact.nom_contact LIKE \'%'.$_POST['find'].'%\' OR contact.prenom_contact LIKE \'%'.$_POST['find'].'%\';

et pour répondre à ta question si mon contact a plusieurs tels, je ne veux pas qu'il ressorte autant de fois que de tel, une fois suffit!
Pour se faire, j'essaie de rentrer tout ça dans un tableau multidimensionnel bien indexé...

J'ai de grosses lacunes en sql (ça se voit), merci en tout cas de t'intéresser à mon problème!
0
crn_c21 Messages postés 302 Date d'inscription samedi 24 janvier 2004 Statut Membre Dernière intervention 4 février 2011
20 mars 2009 à 10:04
essaye ca :

SELECT contact.id_contact, contact.nom_contact, contact.prenom_contact, contact.anniversaire_contact,
tel.tel_tel, tel.type_tel, adresse.nom_adresse, adresse.ville_adresse FROM contact
LEFT OUTER JOIN (SELECT TOP 1 id_contact,tel_tel,type_tel FROM Tel) As Tel
ON Tel.Id_Contact=Contact.Id_Contact
LEFT OUTER JOIN (SELECT TOP 1 Id_Contact,nom_adresse,ville_adresse FROM Adresse)AS Adresse
ON Adresse.Id_Contact=Contact.Id_Contact
WHERE contact.nom_contact LIKE \'%'.$_POST['find'].'%\' OR contact.prenom_contact LIKE \'%'.$_POST['find'].'%\';
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
20 mars 2009 à 11:04
Salut!

Merci pour cette nouvelle réponse!
J'ai essayé... voila:

Syntax error or access violation: 1064 You have an error in your SQL
syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near '1 id_contact,tel_tel,type_tel FROM
Tel) As Tel
ON Tel.Id_Contact=Contact.Id_Cont' at line 3' in /home/seb/www/...

J'ai remarqué des majuscules pour Contact... Je les ai enlevées, mais pas pour les as qui (je comprends bien) sont volontaires.
ça donne :

SELECT contact.id_contact, contact.nom_contact, contact.prenom_contact, contact.anniversaire_contact,
tel.tel_tel, tel.type_tel, adresse.nom_adresse, adresse.ville_adresse FROM contact
LEFT OUTER JOIN (SELECT TOP 1 id_contact,tel_tel,type_tel FROM tel) as Tel
ON (Tel.id_contact=contact.id_contact)
LEFT OUTER JOIN (SELECT TOP 1 id_contact,nom_adresse,ville_adresse FROM adresse) as Adresse
ON (Adresse.id_contact=contact.id_contact)
WHERE contact.nom_contact LIKE \'%'.$_POST['find'].'%\' OR contact.prenom_contact LIKE \'%'.$_POST['find'].'%\';

resultat : la même chose...

Mais je pense qu'il y a une erreur sur la manière de récupérer les infos, parce que si je comprends bien, on va récupérer de cette manière que le premier tel et que la première adresse... alors que je souhaite le contraire, une fois le contact et tous ces tel et adresse...
Désolé si je n'ai pas compris... J'apprends...
Merci de m'expliquer si je me trompe dans la lecture de cette nouvelle requête ;)

PS, ça n'a (j'espère) peut-être rien à voir, mais c'est via PDO que j'exécute mes requêtes... (oui, j'apprends beaucoup de choses en même temps...)

Merci encore
0
crn_c21 Messages postés 302 Date d'inscription samedi 24 janvier 2004 Statut Membre Dernière intervention 4 février 2011
20 mars 2009 à 11:13
J'ai du mal a suivre !!

TU peux ebaucher le tableau que tu veux récupérer?
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
20 mars 2009 à 11:28
Tout à fait!
0
aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
26 mars 2009 à 10:28
salut

si tu es sous mysql, le SELECT TOP 1 ne fonctione pas (c'est une syntaxe SQL Server)

essaie de remplacer par
SELECT  id_contact,tel_tel,type_tel FROM tel LIMIT 1

(verifie la syntaxe exacte de la clause LIMIT dans la doc mysql, je ne connais pas très bien ce SGBDR)

fait de meme pour la sous requete suivante,
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
26 mars 2009 à 10:57
Salut,

Merci de t'intéresser à mon problème.

Le soucis, c'est que ce n'est pas le nombre de tels que je veux limiter...
Je veux interdire les doublons de contact dans le cas ou il y a plusieurs tels ou plusieurs adresses pour un contact donné.

Je fonctionne comme cela actuellement :

SELECT contact.id_contact, contact.nom_contact, contact.prenom_contact, contact.anniversaire_contact,tel.tel_tel, tel.type_tel, adresse.nom_adresse, adresse.ville_adresse
FROM contact
LEFT JOIN tel ON (tel.id_contact = contact.id_contact)
LEFT JOIN adresse ON (adresse.id_contact = contact.id_contact)
WHERE contact.nom_contact LIKE \'%'.$_POST['find'].'%\' OR contact.prenom_contact LIKE \'%'.$_POST['find'].'%\';

et remet en forme le résultat de la requête dans un tableau bien indexé...
Je pensais que je pouvais filtrer des la requête, mais visiblement non...
0
aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
26 mars 2009 à 11:08
Si

tu peux filtrer dés la requete

le probleme quand tu fais une jointure "normale", c'est que si un contact a 2 téléphone, il apparaitra 2 fois dans ton jeu de resultats, une fois avec le premier numéro de téléphone, une fois avec le second.

La solution que te proposais crn_c21 doit eviter cela.

moi j'aurai pas fait autrement, mais je prefere la solution de crn_21
pour info, voici comment j'aurai fait :
si le téléphone retourné n'a pas d'importance dans le cas des contacts qui en ont plusieurs, tu peux aussi faire une jointure normale, mais en demandant le MAX(tel), et en groupant sur le autre champs (GROUP BY id_contact, nom_contact,...)

as tu essayé la solution de crn_21 avec la modif que je t'ai indiquée concernant le TOP/LIMIT ?
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
26 mars 2009 à 12:21
oui, mais ça ne renvoi pas ce que j'attends ou alors ou alors quelque chose m'échappe... dans son exemple, la requête limite le nombre de tel!
J'ai rien compris?
0
aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
26 mars 2009 à 12:26
oui,

comme je t'ai expliqué, si tu as deux tel pour un contact, ce contact apparaitra 2 fois dans ton resultat final

si dans ta requete tu lui dit de ne prendre qu'un tel max par contact, chaque contact n'apparaitra plus qu'une fois

c'est bien ce que tu veux non ?  ou alors c'est moi qui n'ais rien compris...

que te renvoi la requete, et qu'est-ce que tu attends ?
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
26 mars 2009 à 14:11
Non, effectivement, c'est toi qui n'as pas compris ... (je dois mal m'exprimer)
Je veux que tous les tels  et toutes les adresses d'un contact apparaissent, mais que le contact à qui appartient ces tels et adresses, lui, n'apparaisse qu'une seule fois..
c'est plus clair comme ça?
0
crn_c21 Messages postés 302 Date d'inscription samedi 24 janvier 2004 Statut Membre Dernière intervention 4 février 2011
26 mars 2009 à 14:31
Peux-tu esquisser le tableau que tu désires en sortie stp?
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
26 mars 2009 à 14:41
Array
(
[1] => Array
(
[id_contact] => 1
[nom_contact] => shiva
[prenom_contact] => seb
[anniversaire_contact] => 18/07/1978
[tel] => Array
(
[tel1] => 0442434445
[type_tel1] => domicile
[tel2] => 0607080910
[type_tel2] => portable
)
[adr] => Array
(
[nom_adresse1] => sebshiva
[ville_adresse1] => Marseille
)
)
)
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
26 mars 2009 à 14:42
J'aurais du communiquer ça des le début, on m'aurais compris tout de suite...
0
sebshiva Messages postés 194 Date d'inscription lundi 16 mars 2009 Statut Membre Dernière intervention 17 juin 2010 4
8 avril 2009 à 23:14
Merci aieeeuuuu, c'est l'idée que j'émettais dans un de mes premiers post :

"...et de ranger ce résultat dans un tableau bien indexé pour ne pas avoir autant de ligne nom_contact que de tel par ex..." sous-entendu en PHP

Désolé d'avoir pollué le forum... C'était au cas ou il y ai une solution directe en SQL...

Merci en tout cas pour vos aides respectives.
0
Rejoignez-nous