SELECT della vista contiene una sottoquery nella clausola FROM


111

Ho due tabelle e devo creare una vista. Le tabelle sono:

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

Uso la seguente query per farlo. La query senza la parte "crea vista" funziona bene ma con "crea vista", mostra l'errore "SELECT della vista contiene una sottoquery nella clausola FROM". Quale potrebbe essere il problema e la possibile soluzione:

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, no non lo è - quella query può essere riscritta facilmente, il che non è possibile in generale
TMS

Le sottoquery sono supportate in mariadb 10.2dalla versione 10.2.1Vedi - jira.mariadb.org/browse/MDEV-3944
Adarsh ​​Madrecha

Risposte:


157

Come da documentazione:

Documenti MySQL

  • L'istruzione SELECT non può contenere una sottoquery nella clausola FROM.

La soluzione alternativa sarebbe creare una visualizzazione per ciascuna delle tue sottoquery.

Quindi accedi a quelle viste dall'interno della tua vista view_credit_status


17
Notare che l'annidamento delle visualizzazioni può causare gravi danni alle prestazioni.
miguelcobain

1
@miguelcobain, La creazione di una nuova vista solo per annidarla non rimuove le "gravi penalizzazioni delle prestazioni" di cui parli. Allora cosa succede?
Pacerier

28
Ora consentito in 5.7! :-)
François Breton

4
Non consentito neanche in 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

Come dice la più recente documentazione MySQL sulle restrizioni di visualizzazione :

Prima di MySQL 5.7.7, le sottoquery non possono essere utilizzate nella clausola FROM di una vista.

Ciò significa che la scelta di un MySQL v5.7.7 o più recente o l'aggiornamento dell'istanza MySQL esistente a tale versione, rimuoverà completamente questa restrizione sulle visualizzazioni.

Tuttavia, se si dispone di una versione di produzione corrente di MySQL precedente alla v5.7.7, la rimozione di questa restrizione sulle visualizzazioni dovrebbe essere solo uno dei criteri valutati durante la decisione di aggiornare o meno. L'utilizzo delle tecniche alternative descritte nelle altre risposte può essere una soluzione più praticabile, almeno nel periodo più breve.


0

Mi sembra che MySQL 3.6 dia il seguente errore mentre MySQL 3.7 non si sbagli più. Devo ancora trovare qualcosa nella documentazione relativa a questa correzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.