2

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

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

我的 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%'

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

4

5 回答 5

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')
    
于 2011-11-11T00:26:06.207 回答
0

如果basket是一个字符串,就像你的例子所暗示的那样,那么你能得到的最接近的就是使用LIKE '%apples%oranges%grapes%',它可以很容易地用'%'.implode('%', $tags).'%'

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

于 2011-11-11T00:25:14.750 回答
0

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

于 2011-11-11T00:25:32.377 回答
0

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

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

并且将您的数组连接成一个带有 % 分隔符的字符串应该是微不足道的。

于 2011-11-11T00:25:50.453 回答
0

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

考虑:

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

它总是匹配零行。

于 2011-11-11T00:20:19.077 回答