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)


@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


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)

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.


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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.