1

我正在尝试使用加入排除进行 sql 请求。解释:

表格元素

id # name #
 1  Sea
 2  tree

表格颜色

id # name #
 1    green
 2    blue
 3    brown

表关系

element_id # colour_id
     1           2
     2           1
     2           3

我有“获取其中一种颜色的元素”的工作请求。以绿色和蓝色为例:

SELECT element.name, colour.name FROM element
LEFT JOIN relation 
  ON (element.id = relation.element_id)
LEFT JOIN colour
  ON (colour.id = relation.colour_id)
WHERE (relation.colour_id = 1 OR relation.colour_id = 2)

我想请求“获取与所有列出的颜色有关系的元素”。对于绿色棕色,它返回tree

我试图将“OR”更改为“AND”但请求返回 0 结果:/

4

4 回答 4

2

解决此问题的一般方法是过滤值并计算它们在结果中出现的次数。如果相等,则找到所有元素。

select element_id
from relation
where colour_id in (1, 2)
group by element_id
having count (distinct colour_id) = 2

拥有这张表,可以将其加入原始表以生成完整的列集:

SELECT element.name, colour.name 
  FROM relation 
  INNER JOIN
  (
    select element_id
      from relation
     where colour_id in (1, 2)
     group by element_id
    having count (distinct colour_id) = 2
  ) matches
    ON relation.element_id = matches.element_id
  INNER JOIN element
     ON element.id = relation.element_id
  INNER JOIN colour
     ON colour.id = relation.colour_id
于 2012-04-24T19:10:13.753 回答
0

您的条款中有一个错字WHERE- 其中一个 id 是 2(“蓝色”)而不是 3(“棕色”)。它应该是

WHERE (relation.colour_id = 1 OR relation.colour_id = 3)

(或更短的形式:

WHERE relation.colour_id IN (1, 3)

)。

但是请注意,您当前的查询 - 尽管在此修复之后它应该适用于您的示例数据 - 通常不会为您提供正确的结果。它将为您提供与任何指定颜色相关的元素。不过,@Nikola 的回答中给出了正确的解决方案。

于 2012-04-24T19:09:01.363 回答
0

这种类型的查询可以使用一些 SQL 的基于集合的运算符来处理:

哪些元素与所有颜色都有关系?

使用 ALL 运算符(语法可能因数据库而略有不同):

SELECT element.name
FROM element
WHERE ( SELECT colour.id FROM relation 
      INNER JOIN colour ON colour.id = relation.colour_id
      WHERE relation.element_id = element.id )
= ALL ( SELECT colour.id from colour)
;

使用 EXCEPT 运算符:

SELECT element.name
FROM element
WHERE NOT EXISTS 
( SELECT colour.id from colour
   EXCEPT
  SELECT colour.id FROM relation 
  INNER JOIN colour ON colour.id = relation.colour_id
  WHERE relation.element_id = element.id 
)
;
于 2012-04-24T19:19:00.423 回答
0

没有子选择,我建议:

SELECT
    e.id AS id
FROM
    element AS e
    LEFT OUTER JOIN relation AS r ON r.element_id = e.id
    GROUP BY e.id HAVING SUM(CASE WHEN r.colour_id = 1 THEN 1 ELSE 0 END ) = 0
ORDER BY e.id ASC;

在此之后,您可以按 id 选择元素。

于 2015-10-02T14:45:52.653 回答