如何编写包含条件可能并不总是存在的行的自连接

How do I write a self join that includes rows with conditions that might not always be present

以下机票订单查询将删除不包含 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

这是一个相当庞大的查询。因此,在 SO 上回答您的人为您重写整个内容是没有意义的。

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

为此你需要 LEFT JOIN。 (您使用的是旧的逗号连接语法:您正在像 1999 年一样参加派对。)

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

从 table 开始,结果集中的每一行都包含一行。在 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 值来代替缺失值。