[résolu] requete à l'interieur d'une requete ???

as2
Eléphant du PHP | 132 Messages

01 août 2011, 21:12

Bonjour,
En MySql omment faire un truc du genre

select film from ( select film from lien where act=a) where act=b

En gros je veux tout les film avec à la fois l'acteur a et l'acteur b
Modifié en dernier par as2 le 03 août 2011, 15:46, modifié 1 fois.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

02 août 2011, 00:25

Heu simplement en utilisant un simple et dans le where de la requête.

Par exemple
Select truc from bidulles where bidulle=412 and cousin='machin'.

Pour le Sql => http://sqlpro.developpez.com

@+
Il en faut peu pour être heureux ......

as2
Eléphant du PHP | 132 Messages

02 août 2011, 01:43

Heu simplement en utilisant un simple et dans le where de la requête.

Par exemple
Select truc from bidulles where bidulle=412 and cousin='machin'.

Pour le Sql => http://sqlpro.developpez.com

@+
Heu non désolé, c'est pas du tout ce que je veux dire...

On va faire simple : un film comporte plusieurs acteurs !
j'ai une grosse BDD "lien" qui relie la base film et la base acteurs

lien a un champ index, un champ film et un champ acteur

ainsi par exemple, la ligne 1-1-1 signifie que l'acteur avec l'index 1 joue dans le film 1
2-1-2 l'acteur 2 joue egalement dans le film 1
3-1-3 etc
4-2-1 l'acteur 1 joue dans le film2
5-2-4 l'acteur 4 joue dans le film 2
etc...

pour connaitre la filmographie de 1 je fais
select * from lien where act=1

pour connaitre la filmographie de 2 je fais
select * from lien where act=2

etc

çà marche trés bien comme ça.

Maintenant j'essaie de connaitre les films qui réunissent 2 acteurs précis, et c'est là que je bloque...


un genre de

select * from ( select * from lien where act=1) where act=2

mais ça marche pas bien sûr

Des idées ?

Eléphant du PHP | 343 Messages

02 août 2011, 02:04

select * from lien where act=1 and act=2
Développeur web

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

02 août 2011, 09:37

Heu simplement en utilisant un simple et dans le where de la requête.

Par exemple
Select truc from bidulles where bidulle=412 and cousin='machin'.

Pour le Sql => http://sqlpro.developpez.com

@+
Heu non désolé, c'est pas du tout ce que je veux dire...
je te conseil vivement de lire les tutos sur SQL de sqlpro dont je t'ai donné le lien dans mon 1er message.
ce que tu demande est un simple ET booleen !

tu peut aussi regarder http://phpdebutant.org/article117.php si tu veut une version mysql mais la pour le coup c'est la même chose.


@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 12 Messages

02 août 2011, 10:31

Si je comprends bien le besoin, tu souhaiterais avoir la liste des films où il existe un lien avec l'acteur 1 et un lien avec l'acteur 2.
En SQL, cela donnerait:
SELECT * FROM films f WHERE EXISTS ( SELECT id FROM lien l1 WHERE l1.idfilm=f.id AND l1.idact=1) AND  EXISTS ( SELECT id FROM lien l2 WHERE l2.idfilm=f.id AND l2.idact=2) 
Ce n'est pas très joli mais ça devrait fonctionner.
A essayer également: vérifier si les id renvoyés par les sous-select ne sont pas NULL (donc correspondant à une occurrence de la table lien)

ViPHP
xTG
ViPHP | 7331 Messages

02 août 2011, 13:11

Si je comprends bien le besoin, tu souhaiterais avoir la liste des films où il existe un lien avec l'acteur 1 et un lien avec l'acteur 2.
En SQL, cela donnerait:
SELECT * FROM films f WHERE EXISTS ( SELECT id FROM lien l1 WHERE l1.idfilm=f.id AND l1.idact=1) AND  EXISTS ( SELECT id FROM lien l2 WHERE l2.idfilm=f.id AND l2.idact=2) 
Ce n'est pas très joli mais ça devrait fonctionner.
A essayer également: vérifier si les id renvoyés par les sous-select ne sont pas NULL (donc correspondant à une occurrence de la table lien)
Ce n'est absolument pas joli. Tu viens en fait de reproduire le fonctionnement d'un OU booléen. ;)

Eléphanteau du PHP | 12 Messages

02 août 2011, 13:23

Tu viens en fait de reproduire le fonctionnement d'un OU booléen. ;)
Je ne vois pas ce que un OU vient faire ici !!

ViPHP
xTG
ViPHP | 7331 Messages

02 août 2011, 15:54

En effet, je n'avais que lu que trop brièvement ta requête, je l'avais assimilée à ceci en fait :
SELECT * FROM films f 
  INNER JOIN lien
    ON lien.idfilm=f.id
WHERE  lien.idact = 1 OR  lien.idact = 2

as2
Eléphant du PHP | 132 Messages

02 août 2011, 20:10

Bonjour,

déjà merci pour vos réponses, et ensuite pardon de ne pas tout comprendre...
Les requétes croisées, j'ai déjà du mal, mais bon j'en fait, mais là dans l'exemple que vous me donnez il y a apparement une sorte de table temporaire et là je comprends rien (quand vous dites
select * from film f
c'est la base f a coté de film que je comprends pas (et vous mettez des tas de tables lien, l, film, l1, l2 franchement je suis perdu)

Donc si vous le voulez bien on va prendre ma propre table et mes propres données
On laisse tomber la base film et on travaille que sur une seule et unique table que j'ai appellée lien

Voici un petit graphique que j'ai fait avec ce que je veux et la base elle-même

Image

ici, on voit bien que ce sont les films 11 et 16 qui m'interessent car les acteurs 1 et 2 ont joué dedans ensemble


Je supose, je dis bien je suposes, que mon graphique avec ces 2 , heu, bulles, et sa fameuse intersection, c'est çà que vous appellé le ET booléen ?
Si oui merci de me donner des tutos la-dessus car j'en ai pas trouvé sur google...

Mammouth du PHP | 2278 Messages

02 août 2011, 22:52

En s'inspirant de ça (excuse-moi, mais, comme dit Le Lait Pas Écrémé Tout droit (Craeme Allwright pour les intimes, "Le non-beaujolais m'a trop soulagé pour que j'aie le courage de faire mieux que de reproduire un code qui marche):
$clefs_cherchees = array("informatique", "cinema"); 
//$clefs_cherchees = array("informatique", "danse"); 
$clefs_cherchees = implode (",", $clefs_cherchees); //impératif avec la virgule
$requete ="
 select * from article where(FIND_IN_SET(article.mots_cles, '$clefs_cherchees'))";
mais c'est typique de Mysql; j'ai dû imaginer pour passer à sqlite...
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Eléphanteau du PHP | 12 Messages

03 août 2011, 08:53

Bonjour,

déjà merci pour vos réponses, et ensuite pardon de ne pas tout comprendre...
Les requétes croisées, j'ai déjà du mal, mais bon j'en fait, mais là dans l'exemple que vous me donnez il y a apparement une sorte de table temporaire et là je comprends rien (quand vous dites
select * from film f
c'est la base f a coté de film que je comprends pas (et vous mettez des tas de tables lien, l, film, l1, l2 franchement je suis perdu)
f est un alias de film;l1 et l2 sont des alias de lien et permettent de travailler sur deux occurrences distinctes de la table.
Donc si vous le voulez bien on va prendre ma propre table et mes propres données
On laisse tomber la base film et on travaille que sur une seule et unique table que j'ai appellée lien
Pour éviter les incompréhensions, il faudrait la structure exact de la table lien mais également celle de la table film

ViPHP
ViPHP | 2577 Messages

03 août 2011, 11:13

Bonjour,
select A.film from lien A,lien B where A.film = B.film and A.act=a and B.act=b 
select A.film from lien A,lien B
Permet de "créer" une table (Film 1, Film 2, acteur 1, acteur 2)
Imagines un tableau avec en colonne la table film et en ligne la même table film. Le résultat est le contenu de chaque case de ton tableau
where A.film = B.film 
Permet de sélectionner les couples d'acteurs dans le même film
and A.act=a and B.act=b 
Permet de se limiter aux films avec les acteurs souhaités

as2
Eléphant du PHP | 132 Messages

03 août 2011, 15:49

Merci Mazarini,
Ta requète fonctionne trés bien.
Tout était donc une question d'alias, une "table dans la table" si j'ai bien compris ?
Bon j'avoues je vais utilisé dans un 1er temps la requéte telle quelle ou presque, et j'avoue aussi que je la comprends pas trop :roll:

Vous avez pas un tuto sympa sur les alias ?

Mammouth du PHP | 19672 Messages

03 août 2011, 18:06

...et j'avoue aussi que je la comprends pas trop :roll:
Il y a deux points à comprendre avec les alias, ce n'est pas « une table dans la table ».

D'abord, ça facilite la lecture des requêtes surtout lorsqu'elles sont complexes;
Ensuite, lorsqu'on aliase une table, on indique en quelque sorte au SGBD une instance de la table en question. Donc ici, on fait « SELECT * FROM matable ta », MySQL va créer une instance de matable au lieu de piocher directement dans matable. Si on utilise plusieurs fois la même table avec des alias différents, on va avoir des requêtes sur différentes instances. Si tu prends cette même requête et tu tu la fais précéder d'une EXPLAIN, regarde le résultat : les tables indiquées dans le tableau de sortie, ce n'est pas « film » mais chacun des alias.

Donc en résumé, reprenons la requête de Mazarini :
SELECT A.film
FROM lien A, lien B
WHERE A.film = B.film
  AND A.act = a
  AND B.act = b 
Là, on va lister des films en provenance de l'instance « A » de la table lien, mais on va mettre des conditions :
D'abord une condition de jointure et on va créer une seconde instance de la fable lien qui sera « B »
Ensuite, on met des conditions de tri : il faut que le film trouvé dans A soit le même que dans B, mais que celui trouvé dans A ait pour acteur « a » et celui trouvé dans « B » soit « b ».

Reprend ton graphique un peu plus haut : chacun des cercles est une instance de la même table film.

Et pour ta culture, cette même requête aurait pu être écrite avec une jointure normalisée comme ceci :
SELECT A.film
FROM lien A
INNER JOIN lien  B ON A.film = B.film
                  AND A.act = a
                  AND B.act = b
On fait une jointure entre deux alias d'une même table ou si tu veux une auto-jointure. Si tu voulais chercher un film où jouent trois acteurs différents, il faudrait ajouter un troisième alias sur la même table et ajuster la condition de jointure, ça donnerait par exemple :
SELECT A.film
FROM lien A
INNER JOIN lien  B ON A.film = B.film
                  AND A.act = a
                  AND B.act = b
INNER JOIN lien  C ON A.film = C.film
                  AND A.act = a
                  AND C.act = c
Et ça peut continuer en devenant vraiment beaucoup plus compliqué, d'où l'intérêt de bien réfléchir à la structure d'une base de données avant de se lancer dans le code. Pour ne pas devoir faire ce genre de pirouette, il aurait fallu stocker les acteurs dans une table indépendante et avoir une table relationnelle entre les deux puisqu'un film peut avoir 1 à n acteurs et un acteur peut jouer dans 0 à n films. Mais puisque tu as choisi la forme actuelle, on doit ruser et les alias sont une bonne réponse dans ce cas.

Est-ce que c'est plus clair vu comme ça ?
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe: