Page 1 sur 1

problème de requete jointure externe

Posté : 06 avr. 2010, 00:36
par jeanBap
bonjour,

voici les tables:
--
-- Structure de la table `galerie`
--

CREATE TABLE IF NOT EXISTS `galerie` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Reportage_Id` int(11) DEFAULT NULL,
  `ShortName` varchar(25) NOT NULL,
  `LongName` varchar(25) DEFAULT NULL,
  `Date` datetime DEFAULT NULL,
  `Lieu` varchar(50) DEFAULT 'Paris, France',
  `Description` longtext,
  `Audit_Current` enum('Y','N') NOT NULL DEFAULT 'Y',
  `Audit_DateTime` datetime NOT NULL,
  `Position` int(11) NOT NULL DEFAULT '1',
  `Position_Origine` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`Id`),
  KEY `Reportage_Id` (`Reportage_Id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--
-- Contenu de la table `galerie`
--

INSERT INTO `galerie` (`Id`, `Reportage_Id`, `ShortName`, `LongName`, `Date`, `Lieu`, `Description`, `Audit_Current`, `Audit_DateTime`, `Position`, `Position_Origine`) VALUES
(1, 2, 'test1', 'Ceci est un test', '2010-04-05 00:00:00', 'Paris 8', 'test\n\ntesst\n\n<strong>test</strong>test\n\ntesst\n\n<strong>test</strong>test\n\ntesst\n\n<strong>test</strong>test\n\ntesst\n\n<strong>test</strong>', 'Y', '2010-04-05 18:45:08', 1, 0),
(2, 2, '2', '2', '0000-00-00 00:00:00', '', 'Un 2eme ajout de galerie', 'Y', '2010-04-05 18:48:58', 2, 0),
(3, 2, 'test', '', '0000-00-00 00:00:00', '', '<strong>dxvdf</strong>', 'N', '2010-04-05 19:30:04', 3, 0),
(4, 1, 'test', NULL, NULL, 'Paris, France', NULL, 'Y', '0000-00-00 00:00:00', 1, 0);

-- --------------------------------------------------------

--
-- Structure de la table `photo`
--

CREATE TABLE IF NOT EXISTS `photo` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Galerie_Id` int(11) DEFAULT NULL,
  `Commentaire` varchar(25) NOT NULL,
  `Photo` varchar(125) DEFAULT NULL,
  `Miniature` varchar(125) DEFAULT NULL,
  `Audit_Current` enum('Y','N') DEFAULT 'Y',
  `Audit_DateTime` datetime NOT NULL,
  `Position` int(11) NOT NULL DEFAULT '1',
  `Position_Origine` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`Id`),
  KEY `Galerie_Id` (`Galerie_Id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;

--
-- Contenu de la table `photo`
--

INSERT INTO `photo` (`Id`, `Galerie_Id`, `Commentaire`, `Photo`, `Miniature`, `Audit_Current`, `Audit_DateTime`, `Position`, `Position_Origine`) VALUES
(1, 1, 'photo1', '/Galerie/1-test1/mn_01.jpg', '/Galerie_mini/1-test1/mn_01.jpg', 'Y', '0000-00-00 00:00:00', 1, 0),
(2, 1, 'phot2', '/Galerie/1-test1/vs_03.jpg', '/Galerie_mini/1-test1/vs_03.jpg', 'N', '0000-00-00 00:00:00', 2, 2),
(3, 1, 'nico portrait', '/Galerie/1-test1/nico.jpg', '/Galerie_mini/1-test1/nico.jpg', 'N', '0000-00-00 00:00:00', 2, 2),
(4, 1, '', '/Galerie/1-test1/vs_01.jpg', '/Galerie_mini/1-test1/vs_01.jpg', 'N', '0000-00-00 00:00:00', 2, 2),
(5, 2, '', '/Galerie/2-2/vs_04.jpg', '/Galerie_mini/2-2/vs_04.jpg', 'Y', '0000-00-00 00:00:00', 1, 0),
(6, 1, '', '/Galerie/1-test1/vs_01.jpg', '/Galerie_mini/1-test1/vs_01.jpg', 'N', '0000-00-00 00:00:00', 2, 2),
(7, 3, '', '/Galerie/3-test/vs_05.jpg', '/Galerie_mini/3-test/vs_05.jpg', 'N', '0000-00-00 00:00:00', 1, 1),
(8, 2, '', '/Galerie/2-2/miniaturepardefault.JPG', '/Galerie_mini/2-2/miniaturepardefault.JPG', 'Y', '0000-00-00 00:00:00', 2, 0),
(9, 2, '', '/Galerie/2-2/Autobianchi_Bianchina_7259601.jpg', '/Galerie_mini/2-2/Autobianchi_Bianchina_7259601.jpg', 'Y', '0000-00-00 00:00:00', 3, 0);

--
-- Contraintes pour les tables exportées
--

--
-- Contraintes pour la table `galerie`
--
ALTER TABLE `galerie`
  ADD CONSTRAINT `galerie_ibfk_1` FOREIGN KEY (`Reportage_Id`) REFERENCES `reportage` (`Id`) ON DELETE SET NULL ON UPDATE CASCADE;

--
-- Contraintes pour la table `photo`
--
ALTER TABLE `photo`
  ADD CONSTRAINT `Photo_ibfk_1` FOREIGN KEY (`Galerie_Id`) REFERENCES `galerie` (`Id`) ON DELETE SET NULL ON UPDATE CASCADE;


ma requête
SELECT G.Id AS IdGalerie, ShortName, G.Audit_Current AS Audit_Current, P.Audit_Current AS Photo_Current, count( P.Galerie_Id ) AS Nb_Photo
FROM Galerie G
LEFT JOIN Photo P ON G.Id = P.Galerie_Id
GROUP BY G.Id, ShortName, G.Audit_Current, P.Audit_Current
LIMIT 0 , 30
le résultat que j'obtiens:

IdGalerie ShortName Audit_Current Photo_Current Nb_Photo
1 test1 Y Y 1
1 test1 Y N 4
2 2 Y Y 3
3 test N N 1
4 test Y NULL 0


est ce possible en 1 requête d'obtenir ces résultats:

1 test Y Y 1 N 4
2 2 Y Y 3 N 0
3 test N Y 0 N 1
4 test Y NULL 0 NULL 0


J'ai essaye ces 2 requetes en vain...
SELECT distinct
G.Id as IdGalerie, ShortName, G.Audit_Current as Audit_Current,P.Audit_Current as Photo_active, count(P.Audit_Current) as Nb_Photo, P2.Audit_Current as Photo_Desactive, count(P2.Audit_Current) as Nb_Photo_Desactive 
FROM Galerie G LEFT JOIN Photo P ON G.Id=P.Galerie_Id AND P.Audit_Current='Y' left JOIN Photo P2 ON P.Audit_Current<>P2.Audit_Current_Id AND P2.Audit_Current='N' 
Group By G.Id, ShortName, G.Audit_Current, P.Audit_Current, P2.Audit_Current 
SELECT distinct
G.Id as IdGalerie, G.ShortName, G.Audit_Current as Audit_Current,P.Audit_Current as Photo_active, count(P.Audit_Current) as Nb_Photo, P2.Audit_Current as Photo_Desactive, count(P2.Audit_Current) as Nb_Photo_Desactive 
FROM ( Galerie G LEFT JOIN Photo P ON G.Id=P.Galerie_Id AND P.Audit_Current='Y'), (Galerie G2 left JOIN Photo P2 ON G2.Id=P2.Galerie_Id AND P2.Audit_Current='N')
WHERE G.Id=G2.Id AND G.Audit_Current=G2.Audit_Current AND G.ShortName=G2.ShortName 
Group By G.Id, G.ShortName, G.Audit_Current, P.Audit_Current, P2.Audit_Current

mes resultats:


IdGalerie ShortName Audit_Current Photo_active Nb_Photo Photo_Desactive Nb_Photo_Desactive
1 test1 Y Y 4 N 4
2 2 Y Y 3 NULL 0
3 test N NULL 0 N 1
4 test Y NULL 0 NULL 0

en gros faudrait que je fasse
(Galerie Left join Photo active) que je joins a (Galerie left join Photo desactive) mais je n'y suis pas arrivé...

Re: problème de requete jointure externe

Posté : 06 avr. 2010, 19:08
par Patriboom
Il faut que j'avoue, je n'ai pas lu ton message au complet, mais seulement tes requêtes. J'y vois des fautes de syntaxes, c'est ce que je corrige ci-bas.

Note: l'usage du point (.) que tu fais dans le SELECT est juste, il faut refaire la même chose ailleurs. Le point est le marqeur qui sépare la table du champ de cette table.
Note: On ne peut trouver d'espace ni quelqu'autre caractèere spécial dans les noms
De cette requête ( tienne ):

SELECT DISTINCT
G.Id AS IdGalerie, ShortName, G.Audit_Current AS Audit_Current,P.Audit_Current AS Photo_active, count(P.Audit_Current) AS Nb_Photo, P2.Audit_Current AS Photo_Desactive, count(P2.Audit_Current) AS Nb_Photo_Desactive 
FROM Galerie G LEFT JOIN Photo P ON G.Id=P.Galerie_Id AND P.Audit_Current='Y' LEFT JOIN Photo P2 ON P.Audit_Current<>P2.Audit_Current_Id AND P2.Audit_Current='N' 
GROUP BY G.Id, ShortName, G.Audit_Current, P.Audit_Current, P2.Audit_Current
Nous passerons donc à :
SELECT DISTINCT
G.Id AS IdGalerie, ShortName, G.Audit_Current AS Audit_Current,P.Audit_Current AS Photo_active, count(P.Audit_Current) AS Nb_Photo, P2.Audit_Current AS Photo_Desactive, count(P2.Audit_Current) AS Nb_Photo_Desactive 
FROM Galerie AS G RIGHT JOIN Photo Photo AS P ON G.Id=P.Galerie_Id AND P.Audit_Current='Y' RIGHT JOIN Photo AS P2 ON P.Audit_Current<>P2.Audit_Current_Id AND P2.Audit_Current='N' 
GROUP BY G.Id, ShortName, G.Audit_Current, P.Audit_Current, P2.Audit_Current
Bref: j'ai inséré des AS là où tu n'avais que des espaces, pour désigner tes tables jointes.
aussi, j'ai remplacer tes LEFT par des RIGHT puisque dans tes jointures tu mets la table jointes à droite (RIGHT) de la table de référence et non à gauche (LEFT).


Pour déboguer une requête, je fais toujours ainsi.
Dans ma page PHP j'insère un
echo 'Voici la requête'.$requete.'<BR/>'
Puis je copie cette requête dans la fenêtre SQL de PHPMyAdmin. PHPMyAdmin me donne alors des indications sur mes erreurs et fautes de syntaxe.

Re: problème de requete jointure externe

Posté : 06 avr. 2010, 20:01
par jeanBap
ok merci pour les infos, en revanche, ta requête me renvoit cette erreur:
#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 'AS P ON G.Id=P.Galerie_Id AND P.Audit_Current='Y' RIGHT JOIN Photo AS P2 ON P.Au' at line 3

J'ai essayé en retirant les as (et en les remettant) et le double Photo mais ça ne donne pas le résultat attendu.

par contre, j'ai cette requête qui répond à mon besoin, mais je suis obligé de passer par des requête imbriquées.
SELECT A.IdGalerie, A.Audit_Current, A.PhotoActive, A.Nb_PhotoActive, B.PhotoUnActive, B.Nb_PhotoUnActive
FROM (

SELECT G.Id AS IdGalerie, G.Audit_Current, P.Audit_Current AS PhotoActive, count( P.Audit_Current ) AS Nb_PhotoActive
FROM Galerie G
LEFT JOIN Photo P ON G.Id = P.Galerie_Id
AND P.Audit_Current = 'Y'
GROUP BY G.Id, G.Audit_Current, P.Audit_Current
)A
INNER JOIN (

SELECT G1.Id AS IdGalerie, G1.Audit_Current, P2.Audit_Current AS PhotoUnActive, count( P2.Audit_Current ) AS Nb_PhotoUnActive
FROM Galerie G1
LEFT JOIN Photo P2 ON G1.Id = P2.Galerie_Id
AND P2.Audit_Current = 'N'
GROUP BY G1.Id, G1.Audit_Current, P2.Audit_Current
)B ON A.IdGalerie = B.IdGalerie


sinon c'est bien un left qu'il faut utiliser car une galerie peut avoir * photo(s) active(s) et * photo(s) UnActive(s).
J'aurai dû l'indiquer, je souhaitais retourner le nombre (>=0) de photos actives et desactives par galeries.
Merci qd même.

Re: problème de requete jointure externe

Posté : 06 avr. 2010, 20:26
par Patriboom
Est-ce dire que c'est résolu?

Re: problème de requete jointure externe

Posté : 06 avr. 2010, 20:33
par jeanBap
on peut dire que oui, mais comme tu peux le constater j'ai du faire

select //mes champs
from
(select from table1 left table2
)A inner join
(select from table3 left table4
) B
on
//condition sur A et B

n'aurait il pas été possible de faire un unique Select * from ( table1left table2) inner (table3 letf table4) ON condition entre table 1 et table3?

Par simple curiosité...

Re: problème de requete jointure externe

Posté : 07 avr. 2010, 06:21
par Patriboom
Essaie-le et dis-le moi.

Je trouve ta solution finale passablement intéressante.

Re: problème de requete jointure externe

Posté : 08 avr. 2010, 20:24
par jeanBap
Ca ne fonctionne pas!
SELECT G1.Id, G2.Id, P1.Audit_Current, P2.Audit_Current, count(P1.Audit_Current), count(P2.Audit_Current)
FROM
 (Photo P1 RIGHT JOIN Galerie G1 ON P1.Galerie_Id=G1.Id AND P1.Audit_Current='Y') INNER JOIN (Photo P2 RIGHT JOIN Galerie G2 ON P2.Galerie_Id=G2.Id AND P2.Audit_Current='N') ON G1.Id=G2.Id AND G1.Audit_Current=G2.Audit_Current
GROUP BY G1.Id, G2.Id, P1.Audit_Current, P2.Audit_Current
résultat:

Id Id Audit_Current Audit_Current count(P1.Audit_Current) count(P2.Audit_Current)
1 1 Y N 4 4
2 2 Y NULL 3 0
3 3 NULL N 0 1
4 4 NULL NULL 0 0
5 5 NULL NULL 0 0

Par contre
SELECT A.IdGalerie, A.Audit_Current, A.PhotoActive, A.Nb_PhotoActive, B.PhotoUnActive, B.Nb_PhotoUnActive
FROM (

SELECT G.Id AS IdGalerie, G.Audit_Current, P.Audit_Current AS PhotoActive, count( P.Audit_Current ) AS Nb_PhotoActive
FROM Galerie G
LEFT JOIN Photo P ON G.Id = P.Galerie_Id
AND P.Audit_Current = 'Y'
GROUP BY G.Id, G.Audit_Current, P.Audit_Current
)A
INNER JOIN (

SELECT G1.Id AS IdGalerie, G1.Audit_Current, P2.Audit_Current AS PhotoUnActive, count( P2.Audit_Current ) AS Nb_PhotoUnActive
FROM Galerie G1
LEFT JOIN Photo P2 ON G1.Id = P2.Galerie_Id
AND P2.Audit_Current = 'N'
GROUP BY G1.Id, G1.Audit_Current, P2.Audit_Current
)B ON A.IdGalerie = B.IdGalerie

renvoie bien les résultats que je souhaite:

IdGalerie Audit_Current PhotoActive Nb_PhotoActive PhotoUnActive Nb_PhotoUnActive
1 Y Y 1 N 4
2 Y Y 3 NULL 0
3 Y NULL 0 N 1
4 Y NULL 0 NULL 0
5 Y NULL 0 NULL 0

en gros avec la 1ere requête, si une galerie possède X photo Active (P1.Audit_Current='Y') et Z photo desactivé (P2.Audit_Current='N'), elle compte 2 fois les X photo, elle ne la prend pas en compte

Re: problème de requete jointure externe

Posté : 09 avr. 2010, 18:26
par Patriboom
De retour après quelques jours.
Peut-être as-tu trouvé solution.

Question: À quoi servent les champs Aud_Current et Photo_Current.
Comme je les comprends actuellement, ce sont des indicateurs pour savoir s'il y a des audits en souffrance ou des photos dans la banque.
Si tel est le cas, de connaître le nombre de photos ne serait-il pas suffisant (Nb_photo) ?

Dans les requête que tu soumets, il y a sous-entendu qu'un maximum de deux enregistrements existent pour chaque ShortName, ne peut-il pas y en avoir plus?

Bref, ne comprenant pas bien l'utilité des deux champs sus-mentionnés, il me semblerait plus simple de faire une simple addition des Nb_photos selon un critère donné, comme dans la dernière requête que tu affiches.

Sur ma banque d'essai, la requête ci-haut me donne les résultats suivants:
1 test1 Y Y 1
1 test1 Y N 4
2 2 Y Y 3
3 test N N 1
4 test Y NULL 0

Alors, qu'est-ce qui ne fonctionne pas?


Je crois que tu veux grouper par galerie, hein! Alors voici:

Si c'est le cas et que tu cherches plutôt un résultat comme ceci:
4 test Y NULL 0
1 test1 Y Y 9

Voici la requête:
SELECT G.Id AS IdGalerie, ShortName, G.Audit_Current AS Audit_Current, P.Audit_Current AS Photo_Current, count( P.Galerie_Id ) AS Nb_Photo
FROM galerie G
LEFT JOIN photo P ON P.Galerie_Id = G.Id
GROUP BY G.Reportage_id