Widok SELECT zawiera podzapytanie w klauzuli FROM


111

Mam dwie tabele i potrzebuję stworzyć widok. Tabele to:

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

Aby to zrobić, używam następującego zapytania. Zapytanie bez części „tworzenie widoku” działa dobrze, ale w przypadku „tworzenia widoku” wyświetla błąd „SELECT widoku zawiera podzapytanie w klauzuli FROM”. Jaki może być problem i możliwe rozwiązanie:

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, nie, nie jest - to zapytanie można łatwo przepisać, co w ogóle nie jest możliwe
TMS

Podkwerendy są obsługiwane w mariadb 10.2od wersji 10.2.1Zobacz - jira.mariadb.org/browse/MDEV-3944
Adarsh ​​Madrecha

Odpowiedzi:


157

Zgodnie z dokumentacją:

Dokumenty MySQL

  • Instrukcja SELECT nie może zawierać podzapytania w klauzuli FROM.

Rozwiązaniem byłoby utworzenie widoku dla każdego podzapytania.

Następnie uzyskaj dostęp do tych widoków z poziomu swojego widoku view_credit_status


17
Zwróć uwagę, że widoki zagnieżdżone mogą spowodować poważne spadki wydajności.
miguelcobain

1
@miguelcobain, Tworzenie nowego widoku tylko po to, aby go zagnieździć, nie usuwa „poważnych kar wydajności”, o których mówisz. Więc co daje?
Pacerier

28
Teraz dozwolone w 5.7! :-)
François Breton

4
Niedozwolone również w MariaDB
peter

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

Jak mówi najnowsza dokumentacja MySQL dotycząca ograniczeń widoku :

Przed MySQL 5.7.7 podzapytania nie mogą być używane w klauzuli FROM widoku.

Oznacza to, że wybranie MySQL w wersji 5.7.7 lub nowszej lub aktualizacja istniejącej instancji MySQL do takiej wersji całkowicie usunie to ograniczenie widoków.

Jeśli jednak masz bieżącą produkcyjną wersję MySQL starszą niż 5.7.7, usunięcie tego ograniczenia widoków powinno być tylko jednym z kryteriów ocenianych przy podejmowaniu decyzji o aktualizacji lub nie. Korzystanie z technik obejścia opisanych w innych odpowiedziach może być bardziej realnym rozwiązaniem - przynajmniej w krótszej perspektywie.


0

Wydaje mi się, że MySQL 3.6 wyświetla następujący błąd, podczas gdy MySQL 3.7 nie wyświetla już błędów. Nie znalazłem jeszcze niczego w dokumentacji dotyczącej tej poprawki.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.