MySQL UNION SELECT 和 IN 子句

Posted

技术标签:

【中文标题】MySQL UNION SELECT 和 IN 子句【英文标题】:MySQL UNION SELECT and IN clause 【发布时间】:2016-06-08 01:35:56 【问题描述】:

我有两个非常简单的表:t1t2,其中包含以下行:

t1:

id, name
1   PBN

t2:

id, name
100 FIBERHOME

查询 1:

SELECT name FROM t1 UNION SELECT name FROM t2 WHERE id IN (1)

结果是:PBN

查询 2:

SELECT name FROM t1 UNION SELECT name FROM t2 WHERE id IN (100)

结果是:PBN、FIBERHOME

但预期的结果是:FIBERHOME..!是什么原因?

【问题讨论】:

奇怪!您如何期望只有 FIBERHOME,您故意从 t1 中选择名称? 我以为 WHERE 子句是全局的.. 【参考方案1】:

扩展@Knep 的答案,如果你只想要一个WHERE id IN ()

SELECT name FROM (
    SELECT id, name FROM t1
    UNION
    SELECT id, name FROM t2
) unioned
WHERE id IN (1,100)

在速度方面可能不是很好,所以最好测试一下。

还要注意id 需要在子查询中才能在外部WHERE 中使用。

我认为 WHERE 子句是全局的——@szpal

要回答为什么 UNION 中的所有查询都不使用 WHERE 的问题,请考虑两个不共享列的查询。

他们自己:

SELECT id, name FROM x WHERE colA = 123

还有:

SELECT id, name FROM y WHERE colB = 456

然后与(不正确的)单个 WHERE 子句一起:

SELECT id, name FROM x
UNION
SELECT id, name FROM y
WHERE colB = 456 -- But table x doesn't have a colB!

而如果(正确地)WHERE 子句位于每个查询中:

SELECT id, name FROM x
WHERE colA = 123 -- I have a colA, still don't have a colB
UNION
SELECT id, name FROM y
WHERE colB = 456 -- I have a colB, still don't have a colA

每个人都是赢家!

【讨论】:

【参考方案2】:

UNION 总结了两个结果。 在第一个查询中,没有条件,所以它返回 PBN,然后将第二个结果 FIBERHOME 的结果相加。 使用 UNION 你可以尝试:

SELECT name FROM t1 WHERE id IN (100) UNION SELECT name FROM t2 WHERE id IN (100)

【讨论】:

【参考方案3】:

第二个查询的where条件会在union之前执行。

SELECT name FROM t1

将返回

id  name
1   PBN

SELECT name FROM t2 WHERE id IN (100)

将返回

id    name
null  null

联合将以上两个结果合并为

SELECT name FROM t1 UNION SELECT name FROM t2 WHERE id IN (100)

id  name
1   PBN

你可以解决这个问题

SELECT 
name
FROM
    (SELECT 
        *
    FROM
        interns_test_db.t1 UNION SELECT 
        *
    FROM
        interns_test_db.t2) A
WHERE
    ID IN (100)

但这可能会降低性能。

【讨论】:

以上是关于MySQL UNION SELECT 和 IN 子句的主要内容,如果未能解决你的问题,请参考以下文章

MySQL基础语法之子链接查询和特殊查询(union 和 limit)

mysql 优化 explain

MySQL执行计划

MySQL — SQL 语法错误(WHERE IN UNION)

SQL-子查询;union;limit

mysql学习之路_联合查询与子查询