3

我有两张桌子

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));

这将返回eid标签 1 或其子标签之一中存在的所有内容。如果我想返回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 稍后将与条目表连接)

4

1 回答 1

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

JOINandWHERE子句获取它们具有标记1 的所有实体2。但是然后你将它们组合在一起,然后计算这些标签有多少不同的类别。只有当它是 2 时,实体才能通过HAVING子句。

于 2012-03-23T17:15:04.287 回答