почему я должен добавить скобки, чтобы профсоюз работал - PullRequest
1 голос
/ 29 февраля 2020

таблиц:

create table movies (
movie_id int primary key,
title varchar(50));

insert into movies values
(1, 'avengers'), (2, 'frozen2'), (3, 'joker');

create table users (
user_id int primary key,
name varchar(50));

insert into users values
(1, 'daniel'), (2, 'monica'), (3, 'maria'), (4, 'james');

create table movie_rating (
movie_id int,
user_id int,
rating int,
created_at date,
primary key (movie_id, user_id));

insert into movie_rating values
(1, 1, 3, '2020-01-12'),
(1, 2, 4, '2020-02-11'),
(1, 3, 2, '2020-02-12'),
(1, 4, 1, '2020-01-01'),
(2, 1, 5, '2020-02-17'),
(2, 2, 2, '2020-02-01'),
(2, 3, 2, '2020-03-01'),
(3, 1, 3, '2020-02-22'),
(3, 2, 3, '2020-02-25');

вопрос: Напишите следующий SQL запрос:

Найдите имя пользователя, который оценил наибольшее количество фильмов. При значении ie верните лексикографически меньшее имя пользователя.

Найдите имя mov ie с самым высоким средним рейтингом в феврале 2020 года. В случае ie верните лексикографически меньшее значение mov ie name.

Запрос возвращается в 2 строки, формат результата запроса для приведенных выше таблиц:

Result table:
+--------------+
| results      |
+--------------+
| daniel       |
| frozen 2     |
+--------------+

Мое решение, как показано ниже, работает только в том случае, если я добавляю скобки как до, так и после union.

(select u.name results
from users u join movie_rating m on u.user_id = m.user_id
group by m.user_id, u.name
order by count(rating) desc, name
limit 1)
union
(select m.title results
from movies m join movie_rating r 
on m.movie_id = r.movie_id
and r.created_at between '2020-02-01' and '2020-02-29'
group by r.movie_id, m.title
order by avg(r.rating) desc, m.title
limit 1);

если у меня нет скобок, я получаю ошибку. Почему я должен использовать скобки, чтобы заставить union работать?

select u.name results
from users u join movie_rating m on u.user_id = m.user_id
group by m.user_id, u.name
order by count(rating) desc, name
limit 1
union
select m.title results
from movies m join movie_rating r 
on m.movie_id = r.movie_id
and r.created_at between '2020-02-01' and '2020-02-29'
group by r.movie_id, m.title
order by avg(r.rating) desc, m.title
limit 1;
ERROR:  syntax error at or near "union"
LINE 6: union
        ^

Ответы [ 2 ]

2 голосов
/ 29 февраля 2020

Без дополнительных скобок LIMIT допускается только один раз в конце запроса и применяется к результату UNION. Чтобы присоединить LIMIT к каждой скобке SELECT, требуются скобки.

Пожалуйста, отметьте :: https://www.postgresql.org/docs/current/sql-select.html#SQL -UNION

select_statement - это любая инструкция SELECT без ORDER BY, LIMIT, ДЛЯ НИКАКОГО КЛЮЧЕВОГО ОБНОВЛЕНИЯ, ДЛЯ ОБНОВЛЕНИЯ, ДЛЯ ДОЛЯ или ДЛЯ КЛЮЧЕВОГО ДОЛЯ (ORDER BY и LIMIT могут быть присоединены к подвыражению, если оно заключено в круглые скобки. Без скобок эти пункты будут применяться для применения к результату UNION, а не к его правому входному выражению.)

1 голос
/ 29 февраля 2020

В https://dev.mysql.com/doc/refman/8.0/en/union.html

Чтобы применить ORDER BY или LIMIT к отдельному SELECT, поместите предложение в скобки, которые заключают в себе SELECT.

Причина в том, что последнее предложение [group by r.movie_id, m.title order by avg (r.rating) des c, m.title limit 1;] может применяться для последнего SELECT или для UNION , Скобки разрешают эту синтаксию c двусмысленность.

...