2010-08-18 18 views
0
SELECT a.id,i.* FROM ads a 
    INNER JOIN images i ON i.ad_id=a.id 
     GROUP BY a.id 
      LIMIT 10 

Impossible de comprendre, comment choisir des images avec le drapeau "principal" à l'intérieur de la table des images.Problème MySQL avec la déclaration

Pour un a.id peut contenir jusqu'à 3 photos à l'intérieur d'une table d'images, une de ces 3 photos peut avoir un champ principal = 1. Je dois prendre des photos par priorité principale où drapeau est réglé sur 1.

CREATE DATABASE IF NOT EXISTS `test123`; 
USE `test123`; 

CREATE TABLE IF NOT EXISTS `ads` (
    `id` int(10) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=229 DEFAULT CHARSET=utf8; 

INSERT INTO `ads` (`id`) VALUES (217), (225), (226), (228); 

CREATE TABLE IF NOT EXISTS `images` (
    `image_id` int(10) NOT NULL AUTO_INCREMENT, 
    `ad_id` int(10) DEFAULT '0', 
    `main` int(10) DEFAULT '0', 
    `t_0` varchar(255) DEFAULT '0', 
    `t_1` varchar(255) DEFAULT '0', 
    `t_8` varchar(255) DEFAULT '0', 
    PRIMARY KEY (`image_id`), 
    KEY `ad_id` (`ad_id`), 
    KEY `t_0` (`t_0`), 
    KEY `t_1` (`t_1`), 
    KEY `t_8` (`t_8`), 
    KEY `main` (`main`) 
) ENGINE=MyISAM AUTO_INCREMENT=425 DEFAULT CHARSET=utf8; 


INSERT INTO `images` (`image_id`, `ad_id`, `main`, `t_0`, `t_1`, `t_8`) VALUES 
(1, 226, 0, 'img_link1', 'img_link2', 'img_link3'), 
(2, 228, 0, 'img_link1', 'img_link2', 'img_link3'), 
(3, 225, 0, 'img_link1', 'img_link2', 'img_link3'), 
(4, 217, 0, 'img_link1', 'img_link2', 'img_link3'), 
(5, 217, 1, 'img_link1', 'img_link2', 'img_link3'), 
(6, 217, 0, 'img_link1', 'img_link2', 'img_link3'); 

Quelque chose comme ça, mais seulement 1 rang par ads.id

SELECT a.id, i.main AS main 
    FROM images i 
     LEFT JOIN ads a ON a.id=i.ad_id 
      WHERE i.main=1 OR i.main=0 

Résultat requis:

 
id | main | links 
217 | 1 | ... 
225 | 0 | ... 
226 | 0 | ... 
228 | 0 | ... 
+0

Avez-vous besoin de retourner une seule image par courriel 'a.id' ou trois images avec le principal premier? – Quassnoi

+0

Une seule image, de préférence avec l'indicateur principal défini sur 1 – Somebody

Répondre

1

cela devrait faire l'affaire

select ad_id, main, concat(t_0, ', ', t_1, ', ', t_8) as links 
from images 
where main = 0 
group by ad_id having ad_id not in (select ad_id from images where main = 1) 
union all 
select ad_id, main, concat(t_0, ', ', t_1, ', ', t_8) as links from images where main = 1 
+0

Choisit une image avec le drapeau principal pour toutes les images, pas pour une. Ainsi, par exemple, s'il y a plus d'images avec le flag principal, cela n'en choisira qu'une seule. – Somebody

+1

J'ai modifié la requête vérifier –

+0

heh nice oui j'ai obtenu le pourboire. ça marche :) – Somebody

0

Je pense que cela devrait fonctionner:

SELECT a.id,i.* FROM ads a 
INNER JOIN images i 
ON i.ad_id=a.id 
WHERE i.main=1   
GROUP BY a.id 
LIMIT 10 

Edit: Je pense que vous pouvez également déposer la clause GROUP BY puis comme il y aura 1 à 1 correspondance entre A et I

+0

, renvoie une seule ligne avec principale = 1 – Somebody

+0

Il peut être utile d'afficher l'entrée et la sortie d'un échantillon. (p.ex. Ads a ces champs et lignes, Images a ces champs et lignes, je veux que cette sortie soit retournée depuis la jointure des deux tables.) – Kendrick

0

Vous n'avez pas besoin d'un groupe par tout ici:

SELECT ads.id,images.* 
    FROM ads 
     INNER JOIN images ON(Images.ad_id=ads.id) 
    WHERE Images.Flag=x 
    ORDER BY ads.id 
    LIMIT 10 

Si vous souhaitez inclure des images sans le drapeau lorsqu'il n'y a pas de drapeau, ou renvoyer seulement 1 image par annonce même si plusieurs images ont le drapeau, alors la requête sera plus difficile. Vous devrez clarifier pour obtenir une réponse plus ciblée.

Edit: Quelque chose comme cela pourrait fonctionner

SELECT mainImages.Ad_ID2, 
     IFNULL(mainImages.T_0,images.T_0) as T0, 
     IFNULL(mainImages.T_1,images.T_1) as T1 
    FROM images 
     inner join 
      (SELECT ads.id as Ad_ID2,images.* 
       FROM ads 
        LEFT OUTER JOIN images ON(Images.ad_id=ads.id) 
       WHERE Images.Main=1) as mainImages 
      on images.Ad_ID=mainImages.Ad_ID2 
    ORDER BY mainImages.Ad_ID2 
    LIMIT 10 

Il utilise la sous-requête de jointure pour créer une liste d'ID avec des données d'image (uniquement lorsque le drapeau principal est défini), puis réintègre à nouveau la table d'images et remplit les données d'image null de la nouvelle jointure si elle n'existe pas déjà dans la sous-requête. Comme je l'ai dit, je ne peux pas le tester ici, mais je pense que le concept général est solide.

Modifier: Correction d'une requête pour utiliser les tables mises à jour en question.

Edit: nom de colonne modifié sur chaque commentaire

+0

La requête devrait choisir des images, même si elles n'ont pas le drapeau principal à 1. Le drapeau existe seulement pour un but, pointer sur la photo principale, qui devrait être affichée sur la page principale. Btw si je ne veux pas regrouper par identifiant d'annonce, plusieurs lignes sont renvoyées pour un identifiant d'annonce. – Somebody

+0

Vous allez devoir utiliser une sous-requête, puisque vous comparez des valeurs de ligne dans la table. Je vais tenter le coup mais je n'ai pas d'instance MySql au travail pour le tester ... – Kendrick

+0

@Beck "La requête devrait choisir des images, même si elles n'ont pas le drapeau principal défini sur 1" Mais vous juste dit: "Une seule image, de préférence avec le drapeau principal mis à 1" o_O –