2

我有一个item_category有两列的表:item_id, cat_id. 项目到类别是多对多的关系。

如果我的桌子看起来像这样......

item_id | cat_id
1       | 1
1       | 2
2       | 3
2       | 4
3       | 5
3       | 6
4       | 7
4       | 8
5       | 9
5       | 10

...我如何选择一个不同的item_ids列表,其中没有 2 或 7的任何行(产生 2、3、5的 s)?category_iditem_id

4

6 回答 6

5

我会使用聚合和having子句来做到这一点:

select item_id
from item_category ic
group by item_id
having max(cat_id = 2) = 0 and
       max(cat_id = 7) = 0

这是“set-within-sets”查询的一个示例。对于此类查询,使用group bywithhaving是最通用的形式。例如,如果您想确保包含第 3 类,您可以将having子句更改为:

having max(cat_id = 2) = 0 and
       max(cat_id = 7) = 0 and
       max(cat_id = 3) = 1
于 2013-07-18T02:09:10.240 回答
3

尝试这样的事情:

SELECT DISTINCT item_id
FROM table_category
WHERE item_id NOT IN
      (  select distinct item_id 
           from item_category 
          where cat_id in (2,7)
      )
于 2013-07-18T01:31:59.137 回答
2

我会使用 nested SELECT,尽管可能有一些方法可以使用self join来做到这一点。

select item_id 
from item_category t
where not exists (
    select 1 
    from item_category 
    where item_id = t.item_id 
        and cat_id in (2,7)
)
group by item_id;

例子

您也可以改用NOT IN子句:

SELECT DISTINCT item_id 
FROM item_category
WHERE item_id NOT IN (
    select distinct item_id 
    from item_category 
    where cat_id in (2,7));

例子

这两个查询的性能可能相似,但您可以测试您的数据集是否很大。

于 2013-07-18T01:24:10.907 回答
1

就像是:

SELECT DISTINCT item_category.item_id
FROM item_category 
INNER JOIN (
              SELECT item_id ,SUM(CASE cat_id WHEN 2 THEN 1 WHEN 7 THEN 1 ELSE 0 END) AS catcount
              FROM item_category 
              GROUP BY item_id
           ) AS exclude
        ON item_category .item_id = exclude.item_id
            WHERE exclude.catcount=0

更新了答案,我认为这就是您的意思。

于 2013-07-18T01:18:17.213 回答
1

一种方法是

SELECT DISTINCT ITEM_ID
  FROM ITEM_CATEGORY
  WHERE ITEM_ID NOT IN (SELECT DISTINCT ITEM_ID
                          FROM ITEM_CATEGORY
                          WHERE CATEGORY_ID IN (2, 7))

这会产生您想要的结果。如果你想玩得更开心一点,你可以这样做

SELECT DISTINCT ic1.ITEM_ID
  FROM ITEM_CATEGORY ic1
  LEFT OUTER JOIN (SELECT DISTINCT ITEM_ID
                     FROM ITEM_CATEGORY
                     WHERE CATEGORY_ID IN (2, 7)) ic2
    ON ic2.ITEM_ID = ic1.ITEM_ID
  WHERE ic2.ITEM_ID IS NULL

这也可以得到您正在寻找的结果,如果您不熟悉 LEFT OUTER JOIN 的工作原理,可能会花时间费解它的工作原理和工作原理。

SqlFiddle 在这里。

分享和享受。

于 2013-07-18T01:46:39.340 回答
0

可以通过一个简单的子查询来完成:

SELECT DISTINCT item_id
FROM ic
WHERE item_id NOT IN (
  SELECT DISTINCT item_id FROM ic WHERE cat_id IN (2,7)
 );
于 2013-07-18T01:43:24.173 回答