Le SELECT de la vue contient une sous-requête dans la clause FROM

111

J'ai deux tables et j'ai besoin de créer une vue. Les tableaux sont:

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

J'utilise la requête suivante pour ce faire. La requête sans la partie "create view" fonctionne bien mais avec "create view", elle affiche l'erreur "View's SELECT contient une sous-requête dans la clause FROM". Quel pourrait être le problème et la solution possible:

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)
Raouf Athar
la source
@MattFenwick, non ce n'est pas - cette requête peut être réécrite facilement, ce qui n'est pas possible en général
TMS
Les sous-requêtes sont prises en charge dans mariadb à 10.2partir de la version 10.2.1Voir - jira.mariadb.org/browse/MDEV-3944
Adarsh ​​Madrecha

Réponses:

157

Selon la documentation:

Documents MySQL

  • L'instruction SELECT ne peut pas contenir de sous-requête dans la clause FROM.

Votre solution de contournement serait de créer une vue pour chacune de vos sous-requêtes.

Accédez ensuite à ces vues depuis votre vue view_credit_status

Nonym
la source
17
Notez que l'imbrication de vues peut entraîner de graves pénalités de performances.
miguelcobain
1
@miguelcobain, Créer une nouvelle vue juste pour l'imbriquer ne supprime pas les "graves pénalités de performances" dont vous parlez. Alors qu'est-ce qui donne?
Pacerier
28
Maintenant autorisé en 5.7! :-)
François Breton
4
Non autorisé dans MariaDB non plus
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)
Michał Powaga
la source
13

Comme le dit la documentation MySQL la plus récente sur les restrictions d'affichage :

Avant MySQL 5.7.7, les sous-requêtes ne peuvent pas être utilisées dans la clause FROM d'une vue.

Cela signifie que le choix d'un MySQL v5.7.7 ou plus récent ou la mise à niveau de l'instance MySQL existante vers une telle version supprimerait complètement cette restriction sur les vues.

Cependant, si vous avez une version de production actuelle de MySQL antérieure à la v5.7.7, la suppression de cette restriction sur les vues ne devrait être qu'un des critères évalués lors de la décision de mise à niveau ou non. L'utilisation des techniques de contournement décrites dans les autres réponses peut être une solution plus viable - au moins à court terme.

Ombre
la source
0

Il me semble que MySQL 3.6 donne l'erreur suivante tandis que MySQL 3.7 ne fait plus d'erreur. Je n'ai encore rien trouvé dans la documentation concernant ce correctif.

user3809638
la source