Чем заменить union
I'm trying to teach myself and better understand alternative methods to a UNION and discover when I can use joins.
As I'm playing with this I can't seem to get what I want without a UNION. Is it possible to write this in a single query?
Thanks in advance for any guidance or help.
83 1 1 gold badge 1 1 silver badge 5 5 bronze badges No need for DISTINCT in your queries as UNION will remove any duplicates. You could have provided an SQL Fiddle with some test data.Замена Union
Всем привет, знатоки MySQL! Чем можно заменить оператор UNION?
11 1 1 золотой знак 2 2 серебряных знака 8 8 бронзовых знаков А какова цель запроса? Можно заменить Join если нужно сцепить две таблицы по какомуто значению и если ты знаешь, что делаешь. А Union просто сбивает две таблицы в кучу как мусор. У тебя какая цель ? Ничем. Это не заменимый оператор. Только на нём всё и держится!Вообще - никак. Вы бы привели пример, там видно было бы что сделать можно. Там может изначально запрос корявый был, например, такой:
Тогда можно заменить так:
Есть еще некоторые примеры, когда можно избавиться от UNION`a, но без примера ответ только НЕТ
4,819 2 2 золотых знака 22 22 серебряных знака 50 50 бронзовых знаков Чем не подошёл более простой вариант SELECT * FROM table WHERE field in( 1,2) ? @Роман Ракзин, я в комментарии к вашему ответу писал пример, когда это не работает. Пример из моего ответа - это именно пример одной из ситуаций, когда это сделать можно. Ваш пример - одна из возможных реализаций для конкретной ситуации, но не для всего в целом. Вообще же, мой ответ был изначально комментарием, цель которого - получить более детальную информацию по вопросу. Просто кто-то из доброжелателей посчитал его ответом.Традиционно заменяется внешним соединением, но, насколько мне известно, MySQL не поддерживает FULL JOIN.
Оптимизация SQL запроса. Можно ли заменить UNION?
Предположим, есть вот такой абстрактный запрос для отчета:
Т.е несколько раз идет обращение к одной и той же таблице, но считаются разные поля, а каждая составная часть UNION - это отдельная строчка отчета.
Можно ли как-нибудь уйти от UNION и сосчитать все за 1 одно обращение к таблице, но что бы результат был таким же как у UNION?
UPD 1
Протестировал вариант от @MaxU на боевом запросе.
1:04. Не сильно отличается от исходного варианта.
Из некоторых соображений, я сделал анонимизацию таблиц и колонок.
Получил вот такой план:
Очень странно. На 3 верхних уровнях все загоняется во временную таблицу, но на самом нижнм уровне происходит повторное чтение исходной таблицы.
Если убрать UNION, то нижний уровень пропадает. Т.е UNION CTE приводит к повторному чтению.
Конечно, есть предположение, что второго чтения фактически не происходит и данные забираются из кеша, но все равно странно. Почему оптимизатор не решает забрать эти данные из темповой таблицы, а снова лезит и агрегирует все.
UPD 2
Протестировал вариант от @i-one.
Время выполнения: 1:37
Запрос выглядет так:
Как видно по плану, пропало повторное чтение, но время выполнения стало выше варианта, который предложил @MaxU выше.
MySQL. Возможно ли заменить UNION или как оптимизировать запрос?
Есть вот такая БД под названием computer_company
Задание:
Найдите номер модели продукта (ПК, ноутбука или принтера), имеющего самую высокую цену.
Вот, что я написал:
Запрос получился довольно карявый, есть ли более рациональный способ? Необходим ли здесь UNION?
Union можно оставить, но добавить в каждый из подзапросов лимит и сортировку - зачем вам собирать полностью три таблицы, а потом выкидывать всё, кроме первой строки?
А вообще, такая структура БД - антипаттерн. Цена есть у всех продуктов, вне зависимости от типа, поэтому эта колонка должна быть в основной таблице. Не в последнюю очередь для того, чтобы избежать таких кривых выборок.
4 Answers 4
This is one of those things where the old obsolete A,B join syntax really shows it's age, when you have some conditions that must go in a specific ON clause and others that must go in the WHERE clause. It would be very difficult to write this query that way, and even harder to read and understand it later. Better to always write out the full INNER JOIN , LEFT JOIN , etc.
Читайте также: