Page 1 sur 2
Select et limit en jointure
Posté : 21 juin 2008, 17:01
par nelumbo
Bonjour,
J'ai 2 tables: users et picture.
Je souhaite selectionner tous les "username" dans users si une photo est présente dans picture.
username dans picture se nomme profile.
Code : Tout sélectionner
users,picture where picture.profile=users.username AND picture.main=1 AND picture.validated=1
La sélection m'affiche autant de fiche par 'username' que d'entrée dans 'picture' .
J'aimerai mettre une sorte de LIMIT en n'affichant qu'une seule fiche par username même si il y'a plusieurs entrées correspondantes a profile.
Une petite idée ?

Posté : 21 juin 2008, 17:24
par Rei Itchido
Regarde du coté de GROUP BY
Posté : 21 juin 2008, 19:49
par nelumbo
Ca ne fonctionne pas, qu'une seule fiche s'affiche.
Code : Tout sélectionner
picture.profile=users.username AND picture.main=1 AND picture.validated=1 GROUP BY picture.profile
Posté : 22 juin 2008, 12:22
par Ryle
La commande GROUP BY sert lorsque l'on utilise des fonctions regroupant les résultats de plusieurs enregistrements (comme SUM, AVG, ...) pour lier les colonnes qui n'ont pas été groupées, donc à priori rien à voir ici.
Le LIMIT n'aura pas plus d'effet ici, puisque celui-ci se contente de limiter le nombre d'enregistrement retournés par la requête, mais n'affecte en rien les résultats de celle-ci.
Normalement dans ton cas, une simple jointure entre tes deux tables doit suffir, et un
Code : Tout sélectionner
SELECT users.username FROM users, picture WHERE picture.profile=users.usernamedevrait déjà ne te retourner que les username pour lesquels une correspondance a été trouvée dans la table picture.
Si tel n'est pas le cas, donne nous la structure des deux tables (les create table) et la requête complète...
Posté : 22 juin 2008, 15:47
par nelumbo
Ca ne fonctionne pas.
Voici la requête, ou plutôt une partie car celle ci est découpée en plusieurs options de recherche. Pas facile de s'y retrouver.
Code : Tout sélectionner
SELECT * from users,picture where picture.profile=users.username AND picture.main=1 AND picture.validated=1
La table users
Code : Tout sélectionner
CREATE TABLE `users` (
`username` varchar(70) NOT NULL default '',
`email` varchar(255) default NULL,
`password` varchar(70) default NULL,
`ipaddress` varchar(30) default NULL,
`joined` int(11) default '0',
`lastlogin` int(11) default NULL,
`expire_date` int(11) default NULL,
`completed_profile` int(11) default '0',
`pay_upload` smallint(6) default '0',
`pay_contact` smallint(6) default '0',
`pay_webchat` smallint(6) default '0',
`pay_gb` smallint(6) default '0',
`pay_rotate` smallint(6) default '0',
`pay_visitor` smallint(6) default '0',
`pay_fav` smallint(6) default '0',
`pay_match` smallint(6) default '0',
`pay_flirts` smallint(6) default '0',
`delete_me` int(11) default '0',
`f_1` smallint(6) default NULL,
`f_2` varchar(255) default NULL,
`f_4` smallint(6) default NULL,
`f_3` smallint(6) default NULL,
`f_5` smallint(6) default NULL,
`lookingf_1` smallint(6) default NULL,
`lookingf_3` smallint(6) default NULL,
`f_6` smallint(6) default NULL,
`lookingf_6` varchar(255) default NULL,
`betweenFromf_6` varchar(255) default NULL,
`betweenTof_6` varchar(255) default NULL,
`lookingf_2` varchar(255) default NULL,
`betweenFromf_2` varchar(255) default NULL,
`betweenTof_2` varchar(255) default NULL,
`f_7` smallint(6) default NULL,
`f_8` smallint(6) default NULL,
`f_9` smallint(6) default NULL,
`f_10` varchar(255) default NULL,
`f_11` varchar(255) default NULL,
`f_12` smallint(6) default NULL,
`lookingf_12` varchar(255) default NULL,
`f_13` text,
`f_14` varchar(255) default NULL,
`f_15` smallint(6) default NULL,
`f_16` smallint(6) default NULL,
`f_17` varchar(255) default NULL,
`f_18` text,
`visits` int(11) default '0',
`validated` int(11) default NULL,
`video` varchar(190) default NULL,
`notify_flirts` smallint(6) default '1',
`notify_localmsg` smallint(6) default '2',
`notify_important` tinyint(4) default '2',
`f_23` smallint(6) default NULL,
`lookingf_23` smallint(6) default NULL,
`f_25` smallint(6) default NULL,
`lookingf_25` smallint(6) default NULL,
`betweenFromf_3` smallint(6) default NULL,
`betweenTof_3` smallint(6) default NULL,
`betweenFromf_23` smallint(6) default NULL,
`betweenTof_23` smallint(6) default NULL,
PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
La table picture:
Code : Tout sélectionner
CREATE TABLE `picture` (
`id` int(4) NOT NULL auto_increment,
`profile` varchar(50) default NULL,
`filename` varchar(50) default NULL,
`filesize` varchar(50) default NULL,
`filetype` varchar(50) default NULL,
`imagew` varchar(10) default NULL,
`imageh` varchar(10) default NULL,
`main` int(1) default '0',
`validated` int(1) default '0',
`descr` varchar(255) default NULL,
`points` int(11) default '0',
`voters` int(11) default '0',
`grade` double(3,2) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=707 DEFAULT CHARSET=utf8 AUTO_INCREMENT=707 ;
Posté : 22 juin 2008, 19:13
par Shrell
Code : Tout sélectionner
SELECT users.username FROM users, picture WHERE picture.profile=users.username
à première vue je vois deux problèmes dans ce code : d'abord je mettrais les conditions de jointure dans le "ON" et pas dans le "WHERE", mais ça...
ensuite, si un user a posté plusieurs photos, il va ressortir plusieurs fois
donc je dirais :
Code : Tout sélectionner
SELECT DISTINCT username FROM users LEFT JOIN picture ON picture.profile=users.username
Posté : 22 juin 2008, 20:38
par nelumbo
Code : Tout sélectionner
SELECT DISTINCT username FROM users LEFT JOIN picture ON picture.profile=users.username
Cela sélectionne tous les 'username'. Je souhaite uniquement ceux qui ont une photo

.
Posté : 23 juin 2008, 10:01
par Shrell
Dans ce cas :
Code : Tout sélectionner
SELECT DISTINCT username FROM users LEFT JOIN picture ON picture.profile=users.username WHERE picture.id IS NOT NULL
Posté : 23 juin 2008, 10:16
par Rei Itchido
Avec l'utilisation de LEFT JOIN on n'est pas sensé récupérer uniquement les lignes qui ont une correspondance justement?

Sans le WHERE IS NOT NULL j'entends
Posté : 23 juin 2008, 12:05
par Shrell
j'aurais dit pareil... maintenant j'ai répondu avec la tête dans le ***
Donc je ne vois vraiment pas ce qui cloche

Posté : 23 juin 2008, 12:24
par steph29
Avec l'utilisation de LEFT JOIN on n'est pas sensé récupérer uniquement les lignes qui ont une correspondance justement?

Sans le WHERE IS NOT NULL j'entends
Non justement, c'est l'interet du left join
S'il y a une ligne dans A qui répond à la clause WHERE, mais qu'il n'y avait aucune ligne dans B qui répondait à la condition du LEFT JOIN, alors une ligne supplémentaire de B est générée avec toutes les colonnes mises à NULL.
src:
http://dev.mysql.com/doc/refman/5.0/fr/ ... ation.html
Posté : 23 juin 2008, 13:23
par nelumbo
Code : Tout sélectionner
SELECT DISTINCT username FROM users LEFT JOIN picture ON picture.profile=users.username WHERE picture.id IS NOT NULL
Le nombre d'username semble correspondre (fichier test). Mais, il y'a un hic. Lorsque j'intègre la requête à mon script j'ai des 'username' en doublon... Autant d'username affiché que d'entrées dans picture.
if (getParam("pic_only",""))
{
if ($set_validate_on)
$addOnSQL.=" AND picture.profile=users.username AND picture.main=1 AND picture.validated=1";
else
$addOnSQL.=" AND picture.profile=users.username AND picture.main=1";
$addOnSQL.=$sql;
$addOnParams.="&pic_only=1&";
}
dans mon fichier de fonctions:
if (isset($_GET["pic_only"]))
$sql = "SELECT * from users,picture where (";
else
$sql = "SELECT * from users where (";
En fait, pour faire simple, il faudrait que je change uniquement la fin de la requête.
Nota: validate est sur on
Posté : 23 juin 2008, 13:48
par Rei Itchido
Et le DISTINCT?
Posté : 23 juin 2008, 14:02
par Shrell
if (isset($_GET["pic_only"]))
$sql = "SELECT * from users,picture where (";
else
$sql = "SELECT * from users where (";
Je sais je radote

mais tu fais un produit cartésien de tes deux tables, tu vas écrouler ton serveur
pars sur :
if (isset($_GET["pic_only"]))
$sql = "SELECT * from users LEFT JOIN picture ON users.id=picture.profile where ( ";
else
$sql = "SELECT * from users where (";
Et dans ce cas là, étant donné que tu vas rajouter un "AND picture.main=1 AND picture.validated=1", le "IS NOT NULL" est implicite, tu n'en as donc plus besoin
Et comme le fait remarquer
Rei Itchido, ne pas oublier le distinct

Posté : 23 juin 2008, 18:04
par nelumbo
Ca fonctionne
Un
grand merci à tout le monde. Voilà ce qui fonctionne sur mon serveur:
if (isset($_GET["pic_only"]))
$sql = "SELECT DISTINCT username, f_13, f_2, f_12, f_1 FROM users LEFT JOIN picture ON picture.profile=users.username WHERE (";
else
$sql = "SELECT * from users where (";
J'ai du remplacer * par username, f_13, f_2, f_12, f_1 . Bizzarement, le * affiche des doublons et donc fausse les résultats. Va comprendre

.