Выберите объединение с условием where, в то время как столбцы имеют разные имена

Сценарий:

Таблица 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
...

Идентификаторы гарантированно будут разными в двух таблицах.

Я хочу выбрать обе таблицы с помощью объединения (поскольку они были одной таблицей), а затем использовать 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

Но этот запрос возвращает только данные из 1-й таблицы.

Я только что видел, что один из способов добиться этого - обернуть объединение в select.

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–1 тыс. Строк: подзапрос на ~ 20% медленнее.
  • 1k - 100k строк: TODO

person Lemures    schedule 04.07.2018    source источник
comment
SELECT city_id AS 'id', city_name AS 'name' FROM table1 возвращает только id и названия городов из таблицы 1, поэтому: "this query returns only data from 1st table."   -  person Hearner    schedule 04.07.2018
comment
Отредактируйте свой вопрос и покажите нам, чего вы ожидаете в результате   -  person Hearner    schedule 04.07.2018


Ответы (1)


Вы можете добавить одно и то же предложение 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
;

Что касается вашего вопроса, связанного с производительностью, если предложение WHERE оценивается после оценки подзапроса UNION и есть индексы в столбцах id, вы можете не получить выгоду от индексов. Но вы должны проверить план выполнения, чтобы увидеть, правильно ли оптимизатор определяет этот случай и переходит по индексу или нет.

person Flavian-Calinic Stuparu    schedule 04.07.2018
comment
так просто, я чувствую себя тупым. Вопрос. Если бы в обеих таблицах были одинаковые имена столбцов, будет ли мой query1 работать должным образом, или мне все равно нужно будет указывать WHERE в обоих запросах? - person Lemures; 04.07.2018