tags:

views:

77

answers:

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

Can't figure out, how to pick images with flag "main" inside images table.

For one a.id can be up to 3 photos inside images table, one of those 3 photos can have a field main=1. I need to pick photos by priority where flag main is set to 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');

Something like that but only 1 row per 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  

Output required:

id  | main | links
217 | 1    | ...
225 | 0    | ...
226 | 0    | ...
228 | 0    | ...
A: 

I think this should work:

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: I think you could also drop the GROUP BY clause then as there will be a 1 to 1 mapping between A and I

DrDipshit
returns only one row with main=1
Beck
It might help if you showed sample input and output. (e.g. Ads has these fields and rows, Images has these fields and rows, I want this output returned from the join of the two tables.)
Kendrick
A: 

You don't need a group by at all here:

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

If you want to include images without the flag when there is no flag, or return only 1 image per ad even if multiple images have the flag, then the query will be more difficult. You'll have to clarify to get a more targeted answer.

Edit: Something like this might work

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

It uses the subquery join to create a list of IDs with image data (only where the main flag is set) then re-joins the images table again and fills in the null image data from the new join if it doesn't already exist in the subquery. As I said, I can't test it here, but I think the general concept is sound.

Edit: Fixed query to use updated tables in question.

Edit: Changed column name as per comment

Kendrick
Query should pick images, even if they don't have main flag set to 1.Flag exists only for one purpose, to point at main photo, which should be displayed on the main page.Btw if i won't group by ad id, then there are multiple rows returned for one ad id.
Beck
You're going to have to use a subquery, since you're comparing row values within the table. I'll give it a shot but I don't have a MySql instance at work to test it on...
Kendrick
@Beck "Query should pick images, even if they don't have main flag set to 1"But you just said: "Only one image, preferably with main flag set to 1" o_O
DrDipshit
Only one image per ad_id. If 1 image from 3 have main flag, the one with the flag should be picked, if images doesn't have main flag, then random or first is picked.
Beck
erm no i'm wrong. returns 3 rows with same ad_idbtw there is an error which says there are duplicate column ad_idi have renamed to ad_id2 for mainImages
Beck
+1  A: 

this should do the trick

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
ovais.tariq
Picks one image with main flag for all images, not per one. So for example if there are more images with flag main, this will pick only one.
Beck
i have modified the query check it out
ovais.tariq
heh nice oneyea i got the tip.it's working :)
Beck
thats good to know :)
ovais.tariq