让我们考虑以下问题:
我正在尝试在SQL中找到(DB2,但我对其他RDBMS功能很好奇)一种返回可以回答以下问题的方法:
ID为X的图片仅包含蓝色和黄色吗?
一个查询:
ID为Y的图片至少包含蓝色和黄色吗?
ID为Z的图片至少包含蓝色和黄色但没有红色吗?
我想提供以下参数:图片ID,所需颜色列表,不需要的颜色列表。
我设法找到的唯一解决方案基于具有子查询或X联接(X是查询中颜色的数量)和聚合(EXISTS
等)的CASE WHEN
... < / p>
SELECT 1
FROM
picture p
WHERE
p.id = 123
AND EXISTS (
SELECT 1
FROM pic_col pc
INNER JOIN color c ON (c.id = pc.color_id AND c.label = 'blue')
WHERE
pc.picture_id = p.id
)
AND EXISTS (
SELECT 1
FROM pic_col pc
INNER JOIN color c ON (c.id = pc.color_id AND c.label = 'yellow')
WHERE
pc.picture_id = p.id
)
AND NOT EXISTS (
SELECT 1
FROM pic_col pc
INNER JOIN color c ON (c.id = pc.color_id AND c.label = 'red')
WHERE
pc.picture_id = p.id
);
答案 0 :(得分:1)
我喜欢为此目的进行条件聚合。
ID为X的图片仅包含蓝色和黄色吗?
select picture_id
from pic_col pc join
colors c
on pc.color_id = c.id
group by picture_id
having count(*) = sum(case when c.label in ('blue', 'yellow')
ID为Y的图片至少包含蓝色和黄色吗?
select picture_id
from pic_col pc join
colors c
on pc.color_id = c.id
group by picture_id
having sum(case when c.label = 'blue' then 1 else0 end) > 0 and
sum(case when c.label = 'yellow' then 1 else 0 end) > 0;
ID为Z的图片至少包含蓝色和黄色但没有红色吗?
select picture_id
from pic_col pc join
colors c
on pc.color_id = c.id
group by picture_id
having sum(case when c.label = 'blue' then 1 else0 end) > 0 and
sum(case when c.label = 'yellow' then 1 else 0 end) > 0 and
sum(case when c.label = 'red' then 1 else 0 end) = 0;
having
子句将每个图片的每种颜色(或一组颜色)的匹配数量相加。 > 0
表示存在颜色。 = 0
表示没有颜色。