Alias ​​de sous-requête SQL LEFT JOIN

87

J'exécute cette requête SQL:

SELECT wp_woocommerce_order_items.order_id As No_Commande
FROM  wp_woocommerce_order_items
LEFT JOIN 
    (
        SELECT meta_value As Prenom
        FROM wp_postmeta
        WHERE meta_key = '_shipping_first_name'
    ) AS a
ON wp_woocommerce_order_items.order_id = a.post_id
WHERE  wp_woocommerce_order_items.order_id =2198

Et j'obtiens cette erreur:

# 1054 - Colonne inconnue 'a.post_id' dans 'on clause'.

Je pense que mon code est assez simple, mais je ne peux pas le faire correctement. Qu'est-ce que je fais mal?

CharleyXIV
la source

Réponses:

146

Vous n'avez pas sélectionné post_iddans la sous-requête. Vous devez le sélectionner dans la sous-requête comme ceci:

SELECT wp_woocommerce_order_items.order_id As No_Commande
FROM  wp_woocommerce_order_items
LEFT JOIN 
    (
        SELECT meta_value As Prenom, post_id  -- <----- this
        FROM wp_postmeta
        WHERE meta_key = '_shipping_first_name'
    ) AS a
ON wp_woocommerce_order_items.order_id = a.post_id
WHERE  wp_woocommerce_order_items.order_id =2198 
Mahmoud Gamal
la source
1
Merci beaucoup! Je travaille sur un problème similaire et je plaçais la clause WHERE avant LEFT JOIN et recevais une erreur. Cela a vraiment aidé. Merci!
allardbrain
1
mate, vous êtes une légende, venant de pandas en SQL et je me suis gratté la tête pendant une minute chaude en me demandant pourquoi une sous-requête ne fonctionnerait pas. à votre santé.
Manakin
21

Je reconnais que la réponse fonctionne et a été acceptée, mais il existe une manière beaucoup plus propre d'écrire cette requête. Testé sur mysql et postgres.

SELECT wpoi.order_id As No_Commande
FROM  wp_woocommerce_order_items AS wpoi
LEFT JOIN wp_postmeta AS wpp ON wpoi.order_id = wpp.post_id 
                            AND wpp.meta_key = '_shipping_first_name'
WHERE  wpoi.order_id =2198 
EJay
la source
1
Salut, par intérêt, cette méthode serait-elle plus efficace? Sinon, serait-il plus efficace de déplacer le "AND wpp.meta_key = '_shipping_first_name'" vers la clause WHERE?
Chris
1
Honnêtement, je n'ai aucune idée sur l'un ou l'autre de ceux-ci. Je viens de tomber sur cette réponse et j'ai remarqué qu'il y avait un moyen plus propre d'écrire la requête, alors j'ai pensé que je le soulignerais. Désolé, je ne peux pas être plus utile.
EJay
1
Dans MySQL / PostgreSQL, vous pouvez utiliser EXPLAIN SELECT ...ou pour MSSQL SET SHOWPLAN_ALL ONou SET SHOWPLAN_XML ONpour voir comment les lignes sont récupérées. Dans MySQL used filesort, used temporarysont lents et doivent être évités. Quant à la sous-requête jointe, elle nécessite de récupérer toutes les lignes correspondant à la valeur meta_key de la table wp_postmeta avant de rejoindre les identifiants de publication / commande. Il devrait donc être prudent de supposer qu'il serait plus rapide de faire correspondre les identifiants de commande / post et meta_key. En général, une sous-requête comme celle que vous avez utilisée est préférable avec une ORDER BY LIMITqui ne peut pas être filtrée de la requête principale.
Will B.
1
Exemples de résultats de SQLFiddle: Criteria on Join sqlfiddle.com/#!2/e84fa/5 et Subquery on Join sqlfiddle.com/#!2/e84fa/3 Notez que les Subquery on Join22 lignes récupérées de wp_postmeta tandis que le Criteria on Joinseul extrait 1 de wp_postmeta.
Will B.