我有一个存储一堆对象的表。每个对象可以有许多颜色,这些颜色存储在由object_id连接的规范化表中。
如果我去
SELECT `object_name` FROM `objects`
LEFT JOIN `object_color` USING `object_id`
WHERE `object_color` IN ('red', 'blue');
然后我得到'红色'或'蓝色'的对象。我需要获得所有“红色”和“蓝色”的对象。如果我去:
SELECT `object_name` FROM `objects`
LEFT JOIN `object_color` USING `object_id`
WHERE `object_color` = 'red' AND `object_color` = 'blue';
然后我得不到任何东西,因为每一行中只有一个object_color,它不能同时存在。另外,实际上,颜色是另一个表中带有名称的id。为了这个问题,我在这里简化了一切。
我需要能够搜索无限数量的颜色。
由于
修改
object_color仅在object_color表中。
任何物体都会有一次任何一种颜色。
答案 0 :(得分:4)
Select object_name
From objects
Where object_color In('red','blue')
Group By object_name
Having Count(Distinct object_color) = 2
顺便说一句,你从不提及object_color
列派生的表格。如果它来自object_color
表:
Select O.object_name
From objects As O
Join object_color As C
On C.object_id = O.object_id
Where C.object_color In('red','blue')
Group By O.object_name
Having Count(Distinct C.object_color) = 2
上述查询假定给定的object
行可能没有多个相同颜色的object_color
行。但是,正如Joel C所指出的,如果object
有可能有多个object_color
行的红色或蓝色,那么这需要不同的查询。 :击>
Select ...
From objects As O
Where O.object_id In (
Select C1.object_id
From object_color As C1
Where C1.object_color = 'red'
)
And O.object_id In (
Select C1.object_id
From object_color As C1
Where C1.object_color = 'blue'
)
又一个解决方案:
Select O.object_name
From objects As O
Join (
Select C1.object_id, C1.object_color
From object_color As C1
Where C1.color In('red','blue')
Group By C1.object_id, C1.object_color
) As Z
On Z.object_id = O.object_id
Group By O.object_name
Having Count(*) = 2
答案 1 :(得分:2)
我更喜欢ON
而不是USING
:
SELECT o.object_name
FROM objects o
JOIN object_color oc
ON o.object_id = oc.object_id
WHERE oc.object_color IN ( 'red', 'blue' )
GROUP BY o.object_id
HAVING COUNT(o.object_id) = ( SELECT COUNT(*)
FROM ( 'red', 'blue' )
)
假设一个对象不可能有许多具有相同颜色的行。
答案 2 :(得分:1)
您需要多次加入
SELECT `object_name` FROM `objects`
LEFT JOIN `object_color` USING `object_id`
WHERE `object_color` = 'red'
LEFT JOIN `object_color` USING `object_id`
WHERE `object_color` = 'blue' ;
答案 3 :(得分:0)
如果您正在使用的SQL支持INTERSECT,也可以使用它。
SELECT object_name
FROM objects o, objects_color oc
WHERE object_color = 'red'
and o.object_id = oc.object_id
INTERSECT
SELECT object_name
FROM objects o, objects_color oc
WHERE object_color = 'blue'
and o.object_id = oc.object_id
这将与两个表相交,仅显示红色和蓝色与相同对象名称匹配的行。