【问题标题】:Evaluation of multiples 'IN' Expressions in 'WHERE' clauses in mysqlmysql中'WHERE'子句中多个'IN'表达式的评估
【发布时间】:2009-07-28 14:00:23
【问题描述】:

@Cesar 的要求更新。希望我明白你想要什么,如果没有,请回复。夸斯诺伊。

如果我像这样进行SQL 查询:SELECT * FROM TABLE_NAME WHERE b IN (2, 7) AND c IN (3, 9),我可以假设MySQL 将只匹配每个列表中具有相同编号的元素对吗?

也就是说,(2, 3)(7, 9),...?

例如,假设我们有一个这样的表:

+----------+----------+----------+ | PK |乙 | c | +----------+----------+----------+ | 1 | 2 | 3 | +----------+----------+----------+ | 2 | 5 | 4 | +----------+----------+----------+ | 3 | 7 | 9 | +----------+----------+----------+ | 4 | 7 | 4 | +----------+----------+----------+ | 5 | 2 | 9 | +----------+----------+----------+

假设返回的 only 行是 13(而不是 5)是否正确?

【问题讨论】:

  • 您最好在示例中更改“c IN(4,4)”以进行澄清。
  • @Quassnoi:是的,你完全理解我,谢谢!

标签: sql mysql where-clause evaluation


【解决方案1】:
SELECT * FROM TABLE_NAME WHERE b IN(5,7) AND c IN(4,4)

此查询将返回行,其中b57,并且c4

“成对评估”是什么意思?

更新:

我将在示例中再添加一行:

 +----------+----------+----------+
 |    PK    |     b    |     c    |
 +----------+----------+----------+
 |     1    |     2    |     3    |
 +----------+----------+----------+
 |     2    |     5    |     4    |
 +----------+----------+----------+
 |     3    |     7    |     9    |
 +----------+----------+----------+
 |     4    |     7    |     4    |
 +----------+----------+----------+
 |     5    |     2    |     9    |
 +----------+----------+----------+

如果你想匹配整个集合,你可以使用这个语法:

SELECT  *
FROM    table_name
WHERE   (b, c) IN ((2, 3), (7, 9))

这意味着:“返回b2c 同时是3 的所有行,或者b7с 同时是9时间。”

在上面的示例中,此查询将返回行 13

但是如果你反过来重写这个查询,像这样:

SELECT  *
FROM    table_name
WHERE   b IN (2, 7)
        AND c IN (3, 9)

,这意味着“返回b27c39 的所有行。

这将返回行 135,因为行 5 满足第二个查询的条件,但不满足第一个查询的条件。

【讨论】:

  • 是的,这就是我想要做的(整套事情),只是我不会说英语,我想我没有说清楚如果有人可以编辑这个问题为了反映我在寻找什么,请随意。
  • @DevWL: 是的
【解决方案2】:

第 2 行和第 4 行的返回是正确的,尽管您选择 (4,4) 可能会使它更加混乱,因为它是多余的。 AND 表示该行必须满足您的两个条件才能为真。如果查询有 WHERE b IN(5,7) AND c IN(4,9),您将返回第 2、3 和 4 行。

如果你成对考虑,你需要拥有所有的组合。例如,b IN(5,7) AND c IN(4,9) 将产生 (5,4)、(5,9)、(7,4) 和 (7,9) 作为可行的可能组合,而不仅仅是 (5,4) 和 (7, 9)

【讨论】:

    【解决方案3】:

    您可以按顺序评估每个条件,这可能会让您更好地了解这里发生的情况。您的查询表明应选择 b 为 5 或 7 且 c 为 4 的所有值,因此让我们使用第一个条件 (b IN (5,7)) 减少表:

     +----------+----------+----------+
     |    PK    |     b    |     c    |
     +----------+----------+----------+
     |     1    |     2    |     3    | < No match
     +----------+----------+----------+
     |     2    |     5    |     4    | < Match
     +----------+----------+----------+
     |     3    |     7    |     9    | < Match
     +----------+----------+----------+
     |     4    |     7    |     4    | < Match
     +----------+----------+----------+
    

    现在,让我们评估下一个条件,两者都必须为真才能选择一行(c IN (4,4),与c = 4 基本相同):

     +----------+----------+----------+
     |    PK    |     b    |     c    |
     +----------+----------+----------+
     |     2    |     5    |     4    | < Match
     +----------+----------+----------+
     |     3    |     7    |     9    | < No match
     +----------+----------+----------+
     |     4    |     7    |     4    | < Match
     +----------+----------+----------+
    

    其他都是有效的:

     +----------+----------+----------+
     |    PK    |     b    |     c    |
     +----------+----------+----------+
     |     2    |     5    |     4    |
     +----------+----------+----------+
     |     4    |     7    |     4    |
     +----------+----------+----------+
    

    【讨论】:

      【解决方案4】:

      是的,我相信你是对的。

      实际上,'IN' 可以被认为是 (b = 5 OR b = 7) 的简写。这不是它“幕后”的工作方式,但它是一种简单的思考方式。

      对于大型表,多个“IN”子句会导致性能问题。

      编辑:

      上面的海报是正确的,c IN (4, 4) 是没有意义的。你可以简单地说'AND c = 4'。

      如果您将这些子句转换为它们的逻辑等价物,您就会明白原因:

      SELECT * FROM 表 WHERE (b = 5 OR b = 7) AND (c = 4 OR c = 4)

      【讨论】:

      • 他的查询将返回第 2 行和第 4 行是正确的,但不是因为他认为的原因。
      • 啊,刚刚明白他所说的“成对评估”的意思,并澄清了我的答案。
      【解决方案5】:

      您的示例并不能完全说明您的问题,但 多个 IN 子句彼此不相关;它们像任何其他 WHERE 子句一样按顺序进行评估

      因此,以下查询

      SELECT * FROM FOO WHERE b IN(5,7) AND c IN(4,8)
      

      将匹配以下任何一项:

      b c
      ----
      5 4
      5 8
      7 4
      7 8

      IN 可以被认为是或分隔比较的简写。这意味着前面的查询也可以写成(机制略有不同,但概念相同):

      SELECT * FROM FOO WHERE (b = 5 OR b = 7) AND (c = 4 OR c = 8)
      

      因此,在您的示例中,是的,返回的唯一行是 2 和 4。但这并不完全符合您的假设。

      【讨论】:

        猜你喜欢
        • 2021-10-27
        • 1970-01-01
        • 2010-12-17
        • 2013-09-12
        • 1970-01-01
        • 2013-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多