匹配IN子句中的所有值

59

有没有一种方法可以确保 IN 子句中的所有值都被匹配?

例如:

我可以使用 IN (5,6,7,8)

我希望它像多行数据的 AND 一样工作。

更新:我需要从数据库列出符合特定参数的公司。 公司和分类是多对多关系。 我正在使用 Yii 框架。 这是我的控制器代码:

public function actionFilters($list)
{
    $companies = new CActiveDataProvider('Company', array(
        'criteria' => array(
            'condition'=> 'type=0',
            'together' => true,
            'order'=> 'rating DESC',
            'with'=>array(
            'taxonomy'=>array(
                'condition'=>'term_id IN ('.$list.')',
                )
            ),
        ),
    ));
    $this->render('index', array(
        'companies'=>$companies,
    ));
}

你想要什么结果?AND是一个布尔运算符,你想用它对一组数字做什么? - Braiba
1
我不确定你在这里要求什么。当在WHERE子句中使用IN时,将返回所有字段值与其中一个值匹配的行。一个字段不可能同时拥有所有这些值,因此我不知道你从这个理论上的AND()函数中寻找什么。 - Mike Brant
我使用它来根据条件列出数据库中的行。这个条件是一个分类法ID列表。 - Dima Knivets
什么是替代方案? - Dima Knivets
@RPM 需要引用。我认为你可能混淆了在子查询中使用IN的用法,这是因为子查询将针对每个记录运行而变慢。我从未在常量列表上使用IN遇到任何问题;如果有什么问题,我期望它会更快。 - Braiba
事实上,这里接受的答案显示IN比OR快大约2-3倍:https://dev59.com/YHRA5IYBdhLWcg3w6SXZ - Braiba
2个回答

86

你可以像这样做:

select ItemID
from ItemCategory
where CategoryID in (5,6,7,8) <-- de-dupe these before building IN clause
group by ItemID
having count(distinct CategoryID) = 4 <--this is the count of unique items in IN clause above
如果您提供架构和一些样本数据,我可以提供更相关的答案。 SQL Fiddle 示例 如果您想查找具有特定一组CategoryIDs的所有项目而没有其他项目,则可以采用以下方法:
select a.ItemID
from (
    select ItemID, count(distinct CategoryID) as CategoryCount
    from [dbo].[ItemCategory]
    where CategoryID in (5,6,7,8)
    group by ItemID
    having count(distinct CategoryID) = 4 
) a
inner join (
    select ItemID, count(distinct CategoryID) as CategoryCount
    from [dbo].[ItemCategory]
    group by ItemID
) b on a.ItemID = b.ItemID and a.CategoryCount = b.CategoryCount

SQL Fiddle 示例

如果你愿意,你也可以用子查询来实现:

select ItemID 
from ItemCategory 
where ItemID in (
    select ItemID 
    from ItemCategory 
    where CategoryID in (5,6,7,8) 
    group by ItemID 
    having count(distinct CategoryID) = 4
) 
group by ItemID 
having count(distinct CategoryID) = 4

SQL Fiddle Example


7
在什么情况下你会不知道它?这些类型的查询需要动态创建。 - D'Arcy Rittich
1
@DimaKnivets 您解析了查询字符串参数并拆分出唯一的条目,然后使用它们创建参数化的“IN”子句,项目数量用于创建“HAVING”子句。 - D'Arcy Rittich
2
警告:如果有一个项目包含在类别 [5,6,7,8] 中以及任何其他类别中,则此方法实际上无法正常工作。 - Julian J. Tejera
1
@stackFan 不,4是你WHERE子句中唯一项的数量,而不是表本身中的数量。 - D'Arcy Rittich
1
@Diego,请看我上面的更新。 - D'Arcy Rittich
显示剩余7条评论

5
 SELECT ItemID
     FROM ItemCategory
        WHERE (
               (CategoryID = 5) OR 
               (CategoryID = 6) OR 
               (CategoryID = 7) OR 
               (CategoryID = 8)
              )
     GROUP BY ItemID
 HAVING COUNT(DISTINCT CategoryID) = 4

4
HAVING COUNT (CategoryID) 修改为 HAVING COUNT (DISTINCT CategoryID) 可以避免发生误报,如果其中一个值出现了两次(如上面 RedFilter 的回答中所示)。 - Byson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接