Problème de requêtes imbriquées

Résolu
Signaler
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
-
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
-
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

Messages postés
698
Date d'inscription
jeudi 16 janvier 2003
Statut
Membre
Dernière intervention
20 mai 2011
2
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)
Messages postés
302
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
4 février 2011

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'].'%")
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
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?
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
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
Messages postés
302
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
4 février 2011

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?
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
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!
Messages postés
302
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
4 février 2011

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'].'%\';
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
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
Messages postés
302
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
4 février 2011

J'ai du mal a suivre !!

TU peux ebaucher le tableau que tu veux récupérer?
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
Tout à fait!
Messages postés
698
Date d'inscription
jeudi 16 janvier 2003
Statut
Membre
Dernière intervention
20 mai 2011
2
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,
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
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...
Messages postés
698
Date d'inscription
jeudi 16 janvier 2003
Statut
Membre
Dernière intervention
20 mai 2011
2
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 ?
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
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?
Messages postés
698
Date d'inscription
jeudi 16 janvier 2003
Statut
Membre
Dernière intervention
20 mai 2011
2
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 ?
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
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?
Messages postés
302
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
4 février 2011

Peux-tu esquisser le tableau que tu désires en sortie stp?
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
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
)
)
)
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
J'aurais du communiquer ça des le début, on m'aurais compris tout de suite...
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
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.