【问题标题】:Equivalent of "IN" that uses AND instead of OR logic?相当于使用 AND 而不是 OR 逻辑的“IN”?
【发布时间】:2011-12-26 15:39:23
【问题描述】:

我知道我在这里使用动态 SQL 违反了一些规则,但我仍然需要询问。我继承了一个表,其中包含我需要从中提取记录的每张票的一系列标签。

简单示例...我有一个包含“'Apples','Oranges','Grapes'”的数组,我正在尝试检索包含数组中包含的 ALL 项的所有记录.

我的 SQL 如下所示:

 SELECT * FROM table WHERE basket IN ( " + fruitArray + " )

当然相当于:

 SELECT * FROM table WHERE basket = 'Apples' OR basket = 'Oranges' OR basket = 'Grapes'

我很好奇是否有一个函数与 IN (array) 的工作方式相同,只是它使用 AND 而不是 OR,以便我可以获得与以下相同的结果:

 SELECT * FROM table WHERE basket LIKE '%Apples%' AND basket LIKE '%Oranges%' AND basket LIKE '%Grapes%'

我可能只是手动生成整个字符串,但如果可能的话,我想要一个更优雅的解决方案。任何帮助将不胜感激。

【问题讨论】:

  • 简短回答。不。您可以构建子查询,但我认为这不是您要问的。
  • IN 不是一个函数。它是一个运算符。
  • basket 列是什么类型?
  • VARCHAR(512) 我确实将它设置为索引文本,但它太慢了,不值得。

标签: sql-server tags where sql-match-all


【解决方案1】:

这是 SQL 中很常见的问题。基本上有两种解决方案:

  1. 匹配列表中的所有行,按在所有这些行上具有共同值的列进行分组,并确保组中不同值的计数是数组中元素的数量。

    SELECT basket_id FROM baskets
    WHERE basket IN ('Apples','Oranges','Grapes')
    GROUP BY basket_id
    HAVING COUNT(DISTINCT basket) = 3
    
  2. 对数组中的每个不同值进行自连接;只有这样,您才能在一个 WHERE 表达式中比较多行的值。

    SELECT b1.basket_id
    FROM baskets b1
    INNER JOIN baskets b2 USING (basket_id)
    INNER JOIN baskets b3 USING (basket_id)
    WHERE (b1.basket, b2.basket, b3.basket) = ('Apples','Oranges','Grapes')
    

【讨论】:

    【解决方案2】:

    在全文搜索中可能会有类似的东西,但总的来说,我真诚地怀疑这样的运算符在与LIKE 的结合之外是否非常有用。

    考虑:

    SELECT * FROM table WHERE basket ='Apples' AND basket = 'Oranges'
    

    它总是匹配零行。

    【讨论】:

      【解决方案3】:

      如果basket 是一个字符串,就像您的示例所暗示的那样,那么您可以获得的最接近的方法是使用LIKE '%apples%oranges%grapes%',它可以使用'%'.implode('%', $tags).'%' 轻松构建

      这个问题是如果某些“标签”可能包含在其他标签中,例如'supercalifragilisticexpialidocious' LIKE '%super%' 将是真的。

      【讨论】:

        【解决方案4】:

        如果您需要进行LIKE 比较,我认为您不走运。如果您正在以任意顺序进行涉及匹配集的精确比较,您应该查看SELECT 语句的INTERSECTEXCEPT 选项。它们有点令人困惑,但可能非常强大。 (您必须将分隔的字符串解析为表格格式,但无论如何您当然要这样做,不是吗?)

        【讨论】:

          【解决方案5】:

          您要搜索的商品在购物篮中的顺序是否始终相同?如果是,一个 LIKE 就足够了:

          SELECT * FROM table WHERE basket LIKE '%Apples%Oranges%Grapes%';
          

          用 % 分隔符将你的数组连接成一个字符串应该是微不足道的。

          【讨论】:

            猜你喜欢
            • 2012-07-20
            • 2015-09-29
            • 2014-05-11
            • 2023-03-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-08-05
            • 1970-01-01
            相关资源
            最近更新 更多