我有两张桌子
Table "public.tags_to_entities"
Column | Type | Modifiers
--------+---------+-----------
tid | integer | not null
eid | integer | not null
Table "public.tag_tree"
Column | Type | Modifiers
--------+---------+-----------
tid | integer | not null
pid | integer | not null
level | integer |
tag_tree
包含标记之间的所有关系,这意味着SELECT pid FROM tag_tree WHERE tid = ?
将返回该标记的父级。 level
列仅存在或ORDER BY
。
我想返回在每个标记子集中至少有一个标记的所有eid
的列表。使用以下查询执行一个子集
SELECT DISTINCT eid
FROM tags_to_entities
WHERE
tags_to_entities.tid = 1 OR
tags_to_entities.tid IN (SELECT tag_tree.tid FROM tag_tree WHERE tag_tree.pid = 1));
这将返回标记1中存在的所有eid
或其子标记之一。如果我想要返回与eid
和 1
相关的至少一个代码中存在的所有2
。到目前为止我失败的方法是
SELECT DISTINCT eid
FROM tags_to_entities
WHERE
(
tags_to_entities.tid = 1 OR
tags_to_entities.tid IN (SELECT tag_tree.tid FROM tag_tree WHERE tag_tree.pid = 1)) AND
(
tags_to_entities.tid = 2 OR
tags_to_entities.tid IN (SELECT tag_tree.tid FROM tag_tree WHERE tag_tree.pid = 2));
这不起作用,因为tid不能同时为1和2。我怎么解决这个问题? (eid将在稍后的条目表中加入)
答案 0 :(得分:1)
您需要使用GROUP BY
代替DISTINCT
。这允许您使用聚合函数和HAVING
子句。
SELECT
map.eid
FROM
tags_to_entities AS map
INNER JOIN
tag_tree AS tree
ON map.tid = tree.tid
WHERE
(tree.tid = 1 OR tree.pid = 1)
OR (tree.tid = 2 OR tree.pid = 2)
GROUP BY
map.id
HAVING
COUNT(DISTINCT CASE WHEN (tree.tid = 1 OR tree.pid = 1) THEN 1
WHEN (tree.tid = 2 OR tree.pid = 2) THEN 2
END)
= 2
JOIN
和WHERE
子句获取标记为1
或 2
的所有实体。但是,然后将它们组合在一起,然后计算这些标记所在的不同类别。只有当它为2时,实体才能通过HAVING
子句。