SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 10.05.2015 23:05:38

michail_kul
Участник
Зарегистрирован: 10.05.2015
Сообщений: 7

ORDER BY в UNION

Имеем таблицу


CREATE DATABASE Solution;

CREATE TABLE Solution.table_costs (
      id SMALLINT NOT NULL AUTO_INCREMENT,
      d_f DATE NOT NULL,
      price INT(15) NOT NULL,
      category VARCHAR(25) NOT NULL,
      PRIMARY KEY(id));

INSERT INTO Solution.table_costs VALUES(null, '2015-01-15', 31, ‘transport’),
    (null, '2015-01-16', 31, ‘transport’),
    (null, '2015-01-17', 30, ‘tobaco’),
    (null, '2015-02-01', 31, ‘transport’),
    (null, '2015-02-14', 32, ‘beer’),
    (null, '2015-01-01', 30, ‘other’);
 


В результате выборки мы должны получить 3 категории(`category`) с сортировкой по дате(`d_f`).
Первым делом идут категории с точным совпадением цены(`price`), следом с отклонением плюс-минус 5% от цены.

Запрос:


(
SELECT `category`
FROM(
SELECT `category` FROM Solution.table_costs
WHERE `price`=31
ORDER BY `d_f` DESC)
 a
)
UNION
(
SELECT `category`
FROM(
SELECT `category`
FROM Solution.table_costs
WHERE `price`>31 * 0.95 AND `price`<31 * 1.05
 ORDER BY `d_f` DESC)
  b
)
LIMIT 3;
 


Зачем нужны переменные a и b?
Можно ли обойтись без них?
Правильно ли выполнен запрос?

Неактивен

 

#2 11.05.2015 09:35:44

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: ORDER BY в UNION

from подзапрос материализуется во временную таблицу, а каждая таблица в запросе должна иметь имя. a и b это алиасы для соответствующих таблиц.
запрос неверен, так как нет гарантии, что всегда в ответе будут идти сначала результаты первой части union потом второй. Нужна общая сортировка, а сортировку в подзапросах убрать.


select `category` from (
SELECT 1 as x, `category` FROM Solution.table_costs WHERE `price`=31
UNION
SELECT 2, `category` FROM Solution.table_costs WHERE `price`>31 * 0.95 AND `price`<31 * 1.05) t
order by x LIMIT 3;
 

Неактивен

 

#3 11.05.2015 11:47:32

michail_kul
Участник
Зарегистрирован: 10.05.2015
Сообщений: 7

Re: ORDER BY в UNION

Я новичок, и мне сложно так с ходу разобраться. Уже пробовал читать про эти запросы, но в основном не понятно..((

Вот то, что Вы мне пишете во-первых мне не ясно, во-вторых не работает.

Вот что я почерпнул из Вашего ответа:

1. При использовании внутренней сортировки UNION нет гарантии какая часть выведется первой.
2. Подзапрос материализуется во временную таблицу.

Теперь вот что мне не ясно:

1. Что за цифры 1 и 2 после SELECT?
2. Почему в первом SELECT написано 1 as x, а во втором этого нет. И как я понимаю общая сортировка по x приведет к сортировке только первой части запроса.
3. Что за переменная t в конце пятой строчки?
4. Как сделать сортировку обобщенным ORDER BY, с учётом, того, что сначала нужна сортировка первой выборки, а только следом должна идти вторая(её может и не быть, если будут 3 совпадения по сумме в первой выборке)? Подозреваю, что Вы не поняли условие задачи.

Заранее спасибо!

ps: изучал Java и JavaScript гораздо легче чем SQL. Много есть информации, но вся не для новичков. sad

Неактивен

 

#4 11.05.2015 12:17:20

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: ORDER BY в UNION

1. 1 и 2 - это просто числа 1 и 2, они попадут в результат под именем x и по ним будет итоговая сортировка
2. во втором запросе можно не называть x, так как UNION все равно объединит. Можно назвать x, если так понятнее
3. t называет таблицу, которая получается после UNION
4. подозрение неверное, проверяйте работу запроса

Для начинающих можно рекомендовать книгу Харрис "PHP/MySQL для начинающих". И ссылки на SQLinfo http://sqlinfo.ru/forum/viewtopic.php?id=4458

Неактивен

 

#5 11.05.2015 12:36:33

michail_kul
Участник
Зарегистрирован: 10.05.2015
Сообщений: 7

Re: ORDER BY в UNION

1. В результат числа 1 и 2 не попадают.

4. Сортирует не правильно!

Делает две выборки и они отсортированы в обратном порядке. Добавление ключевого слова DESC ситуацию не решает.

Отредактированно michail_kul (11.05.2015 12:38:47)

Неактивен

 

#6 11.05.2015 13:14:40

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: ORDER BY в UNION

select `category` from (
SELECT 1 as x, `category` FROM Solution.table_costs WHERE `price`=31 ORDER BY `d_f` DESC limit 3
UNION
SELECT 2, `category` FROM Solution.table_costs WHERE `price`>31 * 0.95 AND `price`<31 * 1.05 ORDER BY `d_f` DESC limit 3) t
order by x, `d_f` DESC LIMIT 3;
 

Неактивен

 

#7 11.05.2015 13:17:19

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: ORDER BY в UNION

michail_kul написал:

1. В результат числа 1 и 2 не попадают.

потому что в самом внешнем select только `category`
1 и 2 нужны для правильной итоговой сортировки, чтобы сначала были с точной ценой (у этих строк значение вспомогательного поля х равно 1), потом с приближенной (у этих х=2).

Неактивен

 

#8 11.05.2015 13:26:36

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: ORDER BY в UNION

Ещё можно так:

SELECT `category` FROM Solution.table_costs WHERE `price`>31 * 0.95 AND `price`<31 * 1.05 ORDER BY if(price=31,1,2), `d_f` DESC limit 3;

Неактивен

 

#9 11.05.2015 16:10:33

michail_kul
Участник
Зарегистрирован: 10.05.2015
Сообщений: 7

Re: ORDER BY в UNION

vasya написал:

select `category` from (
SELECT 1 as x, `category` FROM Solution.table_costs WHERE `price`=31 ORDER BY `d_f` DESC limit 3
UNION
SELECT 2, `category` FROM Solution.table_costs WHERE `price`>31 * 0.95 AND `price`<31 * 1.05 ORDER BY `d_f` DESC limit 3) t
order by x, `d_f` DESC LIMIT 3;
 

mysql> select `category` from (
    -> SELECT 1 as x, `category` FROM Solution.table_costs WHERE `price`=31 ORDER BY `d_f` DESC limit 3
    -> UNION
    -> SELECT 2, `category` FROM Solution.table_costs WHERE `price`>31 * 0.95 AND `price`<31 * 1.05 ORDER BY `d_f` DESC limit 3) t
    -> order by x, `d_f` DESC LIMIT 3;
ERROR 1221 (HY000): Incorrect usage of UNION and ORDER BY

Неактивен

 

#10 11.05.2015 16:24:56

michail_kul
Участник
Зарегистрирован: 10.05.2015
Сообщений: 7

Re: ORDER BY в UNION

vasya написал:

Ещё можно так:

SELECT `category` FROM Solution.table_costs WHERE `price`>31 * 0.95 AND `price`<31 * 1.05 ORDER BY if(price=31,1,2), `d_f` DESC limit 3;

Вот это красота!!!
Теперь осталось врубить в синтаксис ORDER BY IF. Но тут я уж разберусь!!

Спасибо огромное!

Неактивен

 

#11 11.05.2015 16:33:41

michail_kul
Участник
Зарегистрирован: 10.05.2015
Сообщений: 7

Re: ORDER BY в UNION

michail_kul написал:

vasya написал:

Ещё можно так:

SELECT `category` FROM Solution.table_costs WHERE `price`>31 * 0.95 AND `price`<31 * 1.05 ORDER BY if(price=31,1,2), `d_f` DESC limit 3;

Вот это красота!!!
Теперь осталось врубить в синтаксис ORDER BY IF. Но тут я уж разберусь!!

Спасибо огромное!

Блин, ну что за дела!)) Не могу найти инфу по синтаксису ORDER BY if.

Всё таки прошу помощи.

Объясните.

1. Что делает IF после ORDER BY?
2. Какого назначение аргументов IF?

Неактивен

 

#12 11.05.2015 16:37:49

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Неактивен

 

#13 11.05.2015 16:51:27

michail_kul
Участник
Зарегистрирован: 10.05.2015
Сообщений: 7

Re: ORDER BY в UNION

vasya написал:

http://sqlinfo.ru/forum/viewtopic.php?pid=10466#p10466

IF - функция языка и может использоваться в запросах. Имеет 3 аргумента - условие, значение в случае истинности условия и значение в случае ложности условия.

В запросе: if(price=31,1,2).
Что такое 1 и что такое 2?

Неактивен

 

#14 11.05.2015 16:58:04

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: ORDER BY в UNION

просто числа smile можно выбрать и другие
при сортировке по ним сначала будут идти единички (т.е. точное совпадение цены).

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson