WooCommerce查询订单SQL结果异常,如何正确编写基于meta键值的WHERE条件
问题原因
你出现这个问题的核心原因是wp_woocommerce_order_itemmeta表的存储结构是行式存储自定义字段:同一订单项的不同自定义字段(比如_qty、_tax_class)是存在不同行的,一行只会对应一个meta_key。
当你在WHERE子句里直接加(select oim.meta_value where oim.meta_key = '_tax_class') = 'no_tax'的条件时,会直接过滤掉所有meta_key不等于_tax_class的行,剩下的行里自然没有meta_key = '_qty'的记录,所以你聚合出来的qty字段就是NULL。
正确写法
这里给两种常用的实现方案,都可以在保留_qty字段行的同时完成_tax_class的条件过滤:
方案1:先过滤符合条件的订单项ID再关联
select max( CASE WHEN pm.meta_key = 'id_order' THEN pm.meta_value END ) as 'ID_Order', max( CASE WHEN oim.meta_key = '_qty' THEN oim.meta_value END ) as 'qty' from wp_posts p join wp_postmeta pm on p.ID = pm.post_id join wp_woocommerce_order_items oi on p.ID = oi.order_id -- 先过滤出满足_tax_class='no_tax'的订单项 join ( select order_item_id from wp_woocommerce_order_itemmeta where meta_key = '_tax_class' and meta_value = 'no_tax' ) oi_filter on oi.order_item_id = oi_filter.order_item_id -- 再关联全量的订单项自定义字段拿qty join wp_woocommerce_order_itemmeta oim on oim.order_item_id = oi.order_item_id where post_type = 'shop_order' and p.id = 107291 group by p.id;
方案2:用EXISTS做条件判断,不过滤原表行
select max( CASE WHEN pm.meta_key = 'id_order' THEN pm.meta_value END ) as 'ID_Order', max( CASE WHEN oim.meta_key = '_qty' THEN oim.meta_value END ) as 'qty' from wp_posts p join wp_postmeta pm on p.ID = pm.post_id join wp_woocommerce_order_items oi on p.ID = oi.order_id join wp_woocommerce_order_itemmeta oim on oim.order_item_id = oi.order_item_id where post_type = 'shop_order' and p.id = 107291 -- 判断当前订单项存在符合条件的tax_class记录,不会过滤oim的其他meta行 and EXISTS ( select 1 from wp_woocommerce_order_itemmeta oim2 where oim2.order_item_id = oi.order_item_id and oim2.meta_key = '_tax_class' and oim2.meta_value = 'no_tax' ) group by p.id;
两种方案都可以正常拿到正确的qty值,方案1适合关联表数据量不大的场景,方案2在数据量较大的场景下性能更优。
内容的提问来源于stack exchange,提问作者user14878631
相关产品推荐
相关产品推荐

