我该如何编写一个自我联接,包括具有可能并不总是存在的条件的行

时间:2018-09-15 22:37:11

标签: mysql sql wordpress join key-value

以下针对机票订单的查询将删除不包含G.meta_key值“ pa_co-creation”的行,因为并非每种机票类型都具有该值。如何重新编写此查询以不删除那些行?

SELECT A.meta_value, B.meta_value, D.order_item_name, E.meta_value, F.meta_value, G.meta_value, H.meta_value, I.meta_value, J.meta_value, K.meta_value
FROM wp_postmeta A, wp_postmeta B, wp_woocommerce_order_items D, wp_woocommerce_order_itemmeta E, wp_woocommerce_order_itemmeta F, wp_woocommerce_order_itemmeta G, wp_woocommerce_order_itemmeta H, wp_woocommerce_order_itemmeta I, wp_postmeta J, wp_postmeta K
WHERE A.post_id = B.post_id AND B.post_id = D.order_id AND D.order_item_id = E.order_item_id AND E.order_item_id = F.order_item_id AND F.order_item_id = G.order_item_id AND G.order_item_id = H.order_item_id AND H.order_item_id = I.order_item_id AND A.post_id = J.post_id AND J.post_id = K.post_id
AND A.meta_key = '_billing_first_name' AND B.meta_key= '_billing_last_name' and D.order_item_type = 'line_item' And E.meta_key = 'pa_cabin-preference' AND F.meta_key = '_qty' AND G.meta_key = 'pa_co-creation' AND H.meta_key = 'pa_food' AND I.meta_key = 'pa_gluten' AND J.meta_key = '_billing_email' AND K.meta_key = '_billing_phone' AND D.order_id > 1014

1 个答案:

答案 0 :(得分:1)

这是一个很大的查询。因此,有人用SO回答您为您重写整个内容是没有意义的。

WordPress及其WooCommerce扩展使用键值存储模式来存储任意元数据。正如您所发现的,当缺少某些元数据时,在结果集中保留行需要一些技巧。

您需要LEFT JOIN。 (您使用的是旧的逗号联接语法:像1999年一样参加聚会。)

这是从查询中摘录的一个例子。

从一个表开始,该表在结果集中要包含的每一行都包含一行。在WordPress中,这很可能是wp_posts。

SELECT Z.post_id ...
  FROM wp_posts Z

然后开始像这样加入元数据

SELECT Z.postId, A.meta_value, ...
  FROM wp_posts Z
  LEFT JOIN wp_postmeta A ON Z.post_id = A.post_id AND A.meta_key = '_billing_first_name'

并继续使用该模式,直到您左加入每个元数据项为止,然后您将像2018年一样参加聚会。

为什么这样做?因为普通的JOIN(逗号联接是一种风格)会阻止结果集中失败JOIN条件的行。但是LEFT JOIN保留这些行,并显示NULL值代替丢失的值。