SELECT представления содержит подзапрос в предложении FROM


111

У меня есть две таблицы, и мне нужно создать представление. Таблицы:

credit_orders(id, client_id, number_of_credits, payment_status)
credit_usage(id, client_id, credits_used, date)

Для этого я использую следующий запрос. Запрос без части «создать представление» работает хорошо, но с «создать представление» он показывает ошибку «SELECT представления содержит подзапрос в предложении FROM». В чем может быть проблема и возможное решение:

create view view_credit_status as 
(select credit_orders.client_id, 
        sum(credit_orders.number_of_credits) as purchased, 
        ifnull(t1.credits_used,0) as used 
 from credit_orders
 left outer join (select * from (select credit_usage.client_id, 
                                        sum(credits_used) as credits_used 
                                 from credit_usage 
                                 group by credit_usage.client_id) as t0
                  ) as t1 on t1.client_id = credit_orders.client_id
 where credit_orders.payment_status='Paid'
 group by credit_orders.client_id)


@MattFenwick, нет, это не так - этот запрос можно легко переписать, что в целом невозможно
TMS

Подзапросы поддерживаются в mariadb 10.2начиная с версии 10.2.1See - jira.mariadb.org/browse/MDEV-3944
Адарш Мадреча

Ответы:


157

Согласно документации:

Документы MySQL

  • Оператор SELECT не может содержать подзапрос в предложении FROM.

Обходной путь - создать представление для каждого из ваших подзапросов.

Затем получите доступ к этим представлениям из вашего представления view_credit_status


17
Обратите внимание, что вложение представлений может привести к серьезному снижению производительности.
miguelcobain

1
@miguelcobain, Создание нового представления только для вложения не устраняет "серьезных штрафов за производительность", о которых вы говорите. Так что же дает?
Pacerier

28
Теперь разрешено в 5.7! :-)
François Breton

4
Не разрешено и в MariaDB
Петр

16
create view view_clients_credit_usage as
    select client_id, sum(credits_used) as credits_used 
    from credit_usage 
    group by client_id

create view view_credit_status as 
    select 
        credit_orders.client_id, 
        sum(credit_orders.number_of_credits) as purchased, 
        ifnull(t1.credits_used,0) as used 
    from credit_orders
    left outer join view_clients_credit_usage as t1 on t1.client_id = credit_orders.client_id
    where credit_orders.payment_status='Paid'
    group by credit_orders.client_id)

13

Как сказано в более поздней документации MySQL по ограничениям просмотра :

До MySQL 5.7.7 подзапросы нельзя было использовать в предложении FROM представления.

Это означает, что выбор MySQL v5.7.7 или новее или обновление существующего экземпляра MySQL до такой версии полностью снимет это ограничение на представления.

Однако, если у вас есть текущая производственная версия MySQL, более ранняя, чем v5.7.7, то снятие этого ограничения на представления должно быть только одним из критериев, оцениваемых при принятии решения об обновлении или нет. Использование методов обхода, описанных в других ответах, может быть более жизнеспособным решением - по крайней мере, в краткосрочной перспективе.


0

Мне кажется, MySQL 3.6 выдает следующую ошибку, а MySQL 3.7 больше не выдает ошибок. Я еще ничего не нашел в документации относительно этого исправления.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.