这个人现在已经困扰了我一段时间了.. 我一直在使用MySQL数据库开发自己的CMS;根据与之相关的网站部分,每个上传的图像都被分配到一个类别(我需要这样做,因为每个类别都有自己的处理图像的方式)。
我有各种实体的几个表,一个'images'表和一个关联表:'images_assoc',它们的基本结构如下:
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;
在网站的各个页面中,我需要做的是检索页面元素的列表及其相关图像。我还没有能够用一个选择做到这一点。我现在正在做的是为页面元素运行一个select,然后为每个单个元素运行一个查询以检索任何相关的图像,并使用如下查询:
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
我最初提出的一个解决方案是:
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
但它遗漏了任何没有相关图像的元素,这与左连接的目的完全相反。 后来,我尝试将查询更改为:
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' )
)
但是,查询仍然有问题:我最终得到了一个类似交叉连接的结果,因为稍后会应用类别限制。
有没有人有任何建议? 有关数据库结构的任何提示也是受欢迎的。
答案 0 :(得分:1)
你的idcategory条件永远不会匹配,除非在另一个表中有相应的对应物,这就是为什么没有相应图像的结果“消失”,左连接表现正常。
试试这个:
sql查询:
SELECT some_entity.title, some_entity.description, some_entity.id as entityid, images.id as imageid, images.link, images.name
FROM
some_entity
LEFT JOIN images_assoc ON (some_entity.id = images_assoc.idelement)
LEFT JOIN (SELECT * FROM images WHERE idcategory=1) images ON (images.id = images_assoc.idimage)
或者可能更好(obe只是为了说明它为什么不起作用):
SELECT some_entity.title, some_entity.description, some_entity.id AS entityid, images.id AS imageid, images.link, images.name
FROM some_entity
LEFT JOIN images_assoc ON ( some_entity.id = images_assoc.idelement )
LEFT JOIN images ON ( images.id = images_assoc.idimage )
WHERE images.idcategory = '1' OR images.idcategory IS NULL
测试数据:
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
CREATE TABLE IF NOT EXISTS `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=124 ;
CREATE TABLE IF NOT EXISTS `some_entity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(250) NOT NULL,
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=322 ;
CREATE TABLE IF NOT EXISTS `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=2 ;
INSERT INTO `images` (`id`, `name`, `link`, `idcategory`) VALUES
(123, 'some name', 'foo.jpg', 1);
INSERT INTO `images_assoc` (`id`, `idimage`, `idelement`) VALUES
(1, 123, 321);
INSERT INTO `some_entity` (`id`, `title`, `description`) VALUES
(321, 'test', 'test');