This one has been haunting me for quite a while now..
I have been developing my own CMS using a MySQL database; each uploaded image is assigned to a category, according to which part of the site it is related to (I need to do this since each category has its own way to handle images).
I have several tables for the various entities, an ‘images’ table, and an associative table: ‘images_assoc’, their basic structure is as follows:
CREATE TABLE `images` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL default '',
`link` varchar(255) NOT NULL default '',
`idcategory` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `idcategory` (`idcategory`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
INSERT INTO `images` (`id`, `name`, `link`, `idcategory`) VALUES (1, 'some name', 'foo.jpg', 1);
CREATE TABLE `images_assoc` (
`id` int(11) NOT NULL auto_increment,
`idimage` int(11) NOT NULL default '0',
`idelement` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `idimage` (`idimage`,`idelement`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
INSERT INTO `images_assoc` (`id`, `idimage`, `idelement`) VALUES (1, 1, 2);
CREATE TABLE v`some_entity` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(250) NOT NULL,
`description` text NOT NULL,
-- some other data
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
What I need to do, in the various pages of the site, is to retrieve a list of the page elements together with their related image(s). I have not yet been able to do it with one single select. What I am doing right now is to run a select for the page elements and then run a query for each single element to retrieve any associated image, with a query like this:
SELECT i.id, i.link, i.name
FROM images_assoc AS ia, images AS i
WHERE ia.idelement = '1'
AND i.idcategory = '1'
AND i.id = ia.idimage
one solution I initially came up with was:
SELECT t. * , i.id, i.link, i.name
FROM (
(
(
contents AS t
)
LEFT JOIN images_assoc AS ia ON t.id = ia.idelement
)
LEFT JOIN images AS i ON i.id = ia.idimage
)
WHERE i.idcategory = '1'
AND i.id = ia.idimage
but it left out any element with no associated image, which is the exact contrary of the purpose of the left join.
Later, I tried changing the query to this:
SELECT t. * , i.id, i.link, i.name
FROM (
(
(
contents AS t
)
LEFT JOIN images_assoc AS ia ON t.id = ia.idelement
)
LEFT JOIN images AS i ON ( i.id = ia.idimage
AND i.idcategoriy = '1' )
)
But still, the query is faulty: I end up with a cross-join-like result, since the category restriction is applied later..
Does anyone have any suggestions?
Any tips regarding the database structure are welcome as well..
well your idcategory condition can never match unless there is a corresponding counterpart in the other table, thats why your results with no corresponding image “disappear”, left join is behaving correctly.
try this:
sql query:
or probably better (the obe only to illustrate why it didnt work):
test data: