选择带有条件的联合,而列具有不同的名称

时间:2018-07-04 10:13:42

标签: mysql union union-all

场景:

表1:

city_id     |   city_name       | ...
-------------------------------------
1           |   Aaaa
2           |   Bbb
3           |   Ccc
4           |   Ddd
...

表2:

region_id   |   region_name     | ...
-------------------------------------
1001        |   Qwer
1002        |   Zxcv
1003        |   Vbnm
...

预期结果:

id          |   name     | ...
-------------------------------------
3           |   Ccc
4           |   Ddd
1001        |   Qwer
1002        |   Zxcv
1003        |   Vbnm
...

保证两个表中的ID不同。

我想选择两个带有联合的表(因为它们是1个单个表),然后使用WHERE

query1

SELECT
    city_id     AS 'id',
    city_name   AS 'name'
FROM table1
UNION
SELECT
    region_id   AS 'id',
    region_name AS 'name'
FROM table2
WHERE 'id' > 2

但是此查询仅返回第一张表中的数据。

我刚刚看到实现这一目标的一种方法是将联合包装在一个选择中。

query2

SELECT * FROM (
    SELECT
        city_id     AS 'id',
        city_name   AS 'name'
    FROM table1
    UNION
        region_id   AS 'id',
        region_name AS 'name'
    FROM table2
) AS t
WHERE t.id > 2

不使用子查询就存在孤子吗?

如果没有,那么在这种情况下(大约)使用子查询时,性能如何受到影响?

奖金问题

query2 中,为什么WHERE应用于第一个表?应该不是这样的:

{{
    SELECT
        city_id     AS 'id',
        city_name   AS 'name'
    FROM table1
}}
UNION
{{
    SELECT
        region_id   AS 'id',
        region_name AS 'name'
    FROM table2
    WHERE 'id' > 2
}}

更新

比较子查询和接受的答案

  • 0-1k行:子查询的速度降低了约20%。
  • 1k-10万行:TODO

1 个答案:

答案 0 :(得分:2)

您可以在两个查询中添加相同的WHERE子句:

SELECT
    city_id     AS 'id',
    city_name   AS 'name'
FROM table1
WHERE city_id > 2
UNION
    region_id   AS 'id',
    region_name AS 'name'
FROM table2
WHERE region_id > 2
;

对于与性能有关的问题,如果在评估UNION子查询之后对WHERE子句进行了评估,并且id列上存在索引,则可能无法从索引中受益。但是,您必须检查执行计划,以查看优化器是否正确识别了这种情况,并且没有按索引进行操作。