Aide pour une requête

Eléphant du PHP | 283 Messages

24 sept. 2016, 19:51

Bonjour,
J'ai fais une requête qui fonctionne mais je voudrais la rendre "plus complète". Je vous explique mon soucis. En fait j'ai fais une requête qui sélectionne les dernières notations de films du membre dont c'est la session. Je voudrais inclure dans cette requête les notations de ses séries.

J'ai testé de cette façon mais ça n'a pas fonctionné :
$id_membre = $_SESSION['id'];
$getNoteQuery = $bdd->query("SELECT N.id, N.posteur, N.id_film, N.note, F.titre, F.img, M.pseudo, S.titre, S.img, B.note, B.id FROM note_film N, membres M, fiche_film F, fiche_serie S, note_serie B WHERE N.posteur=M.id AND N.posteur=$id_membre AND N.id_film=F.id AND B.id_serie=S.id ORDER BY N.id, B.id DESC LIMIT 0,6");
while($getNews = $getNoteQuery ->fetch())
Le soucis c'est que ça ne m'affiche que les notations de séries d'un membre alors que je voudrais que ça affiche les 2. Par contre je ne sais pas si ça va être possible de les afficher en fonction de l'id sachant qu'il s'agit de deux tables différentes ?

Merci d'avance pour votre aide.

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

26 sept. 2016, 09:16

salut,
tu peux t'orienter vers l'opérateur union, ceci dit autant faire deux requêtes pour séparer correctement les données vu que tu l'a fait au niveau base.

tu n'avais qu'une seule table avec un type pour indiquer si c'est des fils ou des séries (pourquoi pas des séries de films ;)) cela serait plus simple.
la si tu fais une union entr eles deux requêtes ça va être la merde à l'affichage tu va devoir bidouiller pour afficher correctement (films / série) et au final tu va complexifier la chose.

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

Eléphant du PHP | 283 Messages

26 sept. 2016, 14:38

Salut Moogli !
Merci de ton aide.
J'avais pensé à faire deux requêtes différentes mais le soucis c'est qu'à l'affichage ça affichera en haut les notations séries et en bas les films ?
Il n'y a pas moyen de faire une seule boucle pour afficher les deux ensembles ?

En fait je ne veux pas que ça s'affiche comme ça :
Image

Je voudrais que ça s'affiche de cette manière :
Image

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

26 sept. 2016, 16:58

reste l'union, ou un modèle avec une seule table pour les notation (idutilsiateur, note, idvote, type le type sert ensuite pour les jointures qui a faire des left join sur les tables des séries et films).

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

Eléphant du PHP | 283 Messages

26 sept. 2016, 17:27

D'accord, j'ai testé l'union mais ça ne fonctionne pas correctement. Ça fonctionne quand je retire les tables note_serie et fiche_serie mais pas quand je les laisse.
J'ai ce message d'erreur :
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'N.id_film' in 'on clause'' in /public_html/accueil/accueil.php:181 Stack trace: #0 /public_html/accueil/accueil.php(181): PDO->query('SELECT N.id, N....') #1 ....

Voici le code :
$id_membre = $_SESSION['id'];
$getNewsQuery = $bdd->query("SELECT N.id, N.posteur, N.id_film, N.note, F.titre, F.img, F.realisateur, F.genre, YEAR(F.date_sortie) AS Y, B.id, B.posteur, B.id_serie, B.note, S.titre, S.img, S.realisateur, S.genre, YEAR(S.date_sortie) AS Y
FROM note_film N, fiche_serie S
INNER JOIN fiche_film F ON F.id = N.id_film
INNER JOIN membres M ON M.id = N.posteur
INNER JOIN note_serie B ON B.id_serie = S.id 
WHERE N.posteur= $id_membre AND N.id_film= F.id AND B.posteur= $id_membre AND B.id_serie= S.id ORDER BY N.id, B.id
DESC LIMIT 0,6");
while($getNews = $getNewsQuery->fetch())
{

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

27 sept. 2016, 12:35

pour l'union je pensais plus à cela http://www.w3schools.com/sql/sql_union.asp :)

fait gaffe dans ta requête sql tu as deux alias Y
après c'est étonnant, tu est certain que tu as une colonne "id_film" dans la table note_film (pas un idfilm ou autre ?).

si tu fournis les create table des 5 tables je peu tester.

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

Eléphant du PHP | 283 Messages

27 sept. 2016, 12:46

Merci de ton aide Moogli.
Alors oui je suis sur que j'ai un champs id_film, voici mes 5 tables :

Code : Tout sélectionner

CREATE TABLE IF NOT EXISTS `fiche_serie` ( `id` int(11) NOT NULL, `titre` varchar(255) NOT NULL, `date` date NOT NULL, `id_posteur` bigint(20) NOT NULL, `posteur` varchar(255) NOT NULL, `contenu` text NOT NULL, `genre` varchar(255) NOT NULL, `img` varchar(255) NOT NULL, `critique` text NOT NULL, `video` varchar(255) NOT NULL, `realisateur` varchar(255) NOT NULL, `date_sortie` date NOT NULL, `duree` tinyint(4) NOT NULL, `saison` tinyint(4) NOT NULL, `banniere` varchar(255) NOT NULL, `active` int(11) NOT NULL, `code` bigint(20) DEFAULT NULL ) ENGINE=InnoDB AUTO_INCREMENT=6927 DEFAULT CHARSET=latin1; CREATE TABLE IF NOT EXISTS `fiche_film` ( `id` int(11) NOT NULL, `titre` varchar(255) CHARACTER SET latin1 NOT NULL, `date` date NOT NULL, `id_posteur` bigint(20) NOT NULL, `posteur` varchar(255) CHARACTER SET latin1 NOT NULL, `contenu` text CHARACTER SET latin1 NOT NULL, `synopsis_court` text COLLATE utf8_unicode_ci NOT NULL, `genre` varchar(255) CHARACTER SET latin1 NOT NULL, `img` varchar(255) CHARACTER SET latin1 NOT NULL, `critique` text CHARACTER SET latin1 NOT NULL, `video` varchar(255) CHARACTER SET latin1 NOT NULL, `realisateur` varchar(255) CHARACTER SET latin1 NOT NULL, `date_sortie` date NOT NULL, `duree` mediumint(9) NOT NULL, `banniere` varchar(255) CHARACTER SET latin1 NOT NULL, `active` int(11) NOT NULL, `code` bigint(20) DEFAULT NULL ) ENGINE=InnoDB AUTO_INCREMENT=43526 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; CREATE TABLE IF NOT EXISTS `note_film` ( `id` int(11) NOT NULL, `posteur` int(11) NOT NULL, `id_film` bigint(20) NOT NULL, `note` int(11) NOT NULL ) ENGINE=InnoDB AUTO_INCREMENT=306 DEFAULT CHARSET=latin1; CREATE TABLE IF NOT EXISTS `note_serie` ( `id` int(11) NOT NULL, `posteur` int(11) NOT NULL, `id_serie` int(11) NOT NULL, `note` int(11) NOT NULL ) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=latin1; CREATE TABLE IF NOT EXISTS `membres` ( `id` int(11) NOT NULL, `pseudo` varchar(100) NOT NULL, `motdepasse` varchar(100) NOT NULL, `email` varchar(255) NOT NULL, `news_letter` tinyint(1) NOT NULL, `avatar` varchar(255) CHARACTER SET latin1 NOT NULL, `banniere` varchar(255) CHARACTER SET latin1 NOT NULL, `date_naissance` date NOT NULL, `sexe` tinyint(11) NOT NULL, `date` date NOT NULL ) ENGINE=MyISAM AUTO_INCREMENT=51 DEFAULT CHARSET=utf8;
Du coup pour l'union, j'ai regardé le lien que tu m'as donné. On fait comment pour préciser les jointures entre d'autres tables ? Comme pour associer la table membres et note_film, note_serie ?

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

27 sept. 2016, 17:14

j'ai le même problème que toi. D'après la doc
Previously, the comma operator (,) and JOIN both had the same precedence, so the join expression t1, t2 JOIN t3 was interpreted as ((t1, t2) JOIN t3). Now JOIN has higher precedence, so the expression is interpreted as (t1, (t2 JOIN t3)). This change affects statements that use an ON clause, because that clause can refer only to columns in the operands of the join, and the change in precedence changes interpretation of what those operands are.

Example:

CREATE TABLE t1 (i1 INT, j1 INT);
CREATE TABLE t2 (i2 INT, j2 INT);
CREATE TABLE t3 (i3 INT, j3 INT);
INSERT INTO t1 VALUES(1,1);
INSERT INTO t2 VALUES(1,1);
INSERT INTO t3 VALUES(1,1);
SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);
Previously, the SELECT was legal due to the implicit grouping of t1,t2 as (t1,t2). Now the JOIN takes precedence, so the operands for the ON clause are t2 and t3. Because t1.i1 is not a column in either of the operands, the result is an Unknown column 't1.i1' in 'on clause' error. To allow the join to be processed, group the first two tables explicitly with parentheses so that the operands for the ON clause are (t1,t2) and t3:

SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
Alternatively, avoid the use of the comma operator and use JOIN instead:

SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);

pour l'union tu fais les deux requêtes et tu mets union entre les deux ;)

select * from latable1
union
select * from latable2

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

Eléphant du PHP | 283 Messages

27 sept. 2016, 19:08

Donc on est obligé de passer par UNION ?

J'ai essayé une requête toute simple mais ça ne fonctionne pas.
$id_membre = $_SESSION['id'];
$getNewsQuery = $bdd->query("SELECT * FROM note_serie
WHERE posteur=$id_membre
UNION SELECT * FROM fiche_serie");
while($getNews = $getNewsQuery->fetch())
{

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

28 sept. 2016, 10:49

pour union il faut le même nombre de colonne (quitte a ajouter des nul avec aliais)

pour le reste il faut tester les solutions de la doc, au pire la version de 1999 sans utiliser join et select sur les 5 tables et critère de jointure dans le prédicat (where)

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

Eléphanteau du PHP | 25 Messages

28 sept. 2016, 15:58

Bonjour,

Déjà vous avez un souci au niveau de votre ennoncé par rapport à votre structure de table:
"qui sélectionne les dernières notations de films du membre" or vous n'avez pas daté les notations des membres pour chaque film et chaque série.

Ensuite sauf erreur de ma part, votre requête devrait ressembler à ceci:

Code : Tout sélectionner

SELECT M.id,M.pseudo,NF.note,F.titre, 'F' FROM membres M INNER JOIN note_film NF ON M.id=NF.posteur INNER JOIN fiche_film F ON NF.id_film=F.id UNION SELECT M.id,M.pseudo,NS.note,F.titre, 'S' FROM membres M INNER JOIN note_serie NS ON M.id=NS.posteur INNER JOIN fiche_serie S ON NS.id_serie=S.id
Il ne vous reste qu'à sélectionner l'utilisateur courant dans la clause WHERE

++
Architecte de données & applications web
MCSE Data Management & Analytics

Eléphant du PHP | 283 Messages

01 oct. 2016, 16:33

Ca fonctionne merci beaucoup Jc71 !
Du coup j'aurais une simple question, c'est normal que ça m'affiche d'abord les notes films et ensuite en dessous les notes séries ? On ne peut pas faire en sorte que ça s'affiche en fonction de la date si j'ajoute la date à la table note ?

Voici le code :
$id_membre = $_SESSION['id'];
$getNewsQuery = $bdd->query("SELECT M.id,M.pseudo,NF.note,F.titre, F.img, F.realisateur,year(F.date_sortie) as 'y'
FROM membres M
INNER JOIN note_film NF ON M.id=NF.posteur
INNER JOIN fiche_film F ON NF.id_film=F.id
WHERE NF.posteur=$id_membre

UNION

SELECT M.id,M.pseudo,NS.note,S.titre, S.img, S.realisateur, year(S.date_sortie) as 'y'
FROM membres M
INNER JOIN note_serie NS ON M.id=NS.posteur
INNER JOIN fiche_serie S ON NS.id_serie=S.id
WHERE NS.posteur=$id_membre");
while($getNotes = $getNewsQuery->fetch())
{

Eléphanteau du PHP | 25 Messages

18 oct. 2016, 21:06

Bonsoir,

Oui c'est possible avec une clause where globale à la requête.

Bonne soirée.
Architecte de données & applications web
MCSE Data Management & Analytics

Eléphanteau du PHP | 25 Messages

23 oct. 2016, 16:06

Je voulais dire ORDER BY désolé un moment d'égarement.
Architecte de données & applications web
MCSE Data Management & Analytics