我有一个简单的Select语句如下:
select p.ID as order_id,
p.post_date,
max(CASE WHEN pm.meta_key = '_billing_email' and p.ID = pm.post_id
THEN pm.meta_value END) as billing_email,
max(CASE WHEN pm.meta_key = '_billing_first_name' and p.ID = pm.post_id
THEN pm.meta_value END) as _billing_first_name,
max(CASE WHEN pm.meta_key = '_billing_last_name' and p.ID = pm.post_id
THEN pm.meta_value END) as _billing_last_name,
max(CASE WHEN pm.meta_key = '_order_total' and p.ID = pm.post_id
THEN pm.meta_value END) as order_total,
max(CASE WHEN pm.meta_key = '_order_tax' and p.ID = pm.post_id
THEN pm.meta_value END) as order_tax,
max(CASE WHEN pm.meta_key = '_paid_date' and p.ID = pm.post_id
THEN pm.meta_value END) as paid_date
from wp_posts as p,
wp_postmeta as pm
where post_type = 'shop_order'
and p.ID = pm.post_id
and
and post_status = 'wc-completed'
group by p.ID
有人建议我应该使用JOIN语法 - 我假设代替CASE WHEN。我已经开始研究JOIN版本了,但到目前为止它看起来并不那么冗长 - 只是想知道这是否确实是最佳实践并且处理效率更高?
我是新手学习SQL并学习,所以我很乐意看到如何使用JOIN重写这个例子,因为我可能会以错误的方式解决这个问题。
答案 0 :(得分:1)
在MySQL中基本上有两种旋转数据的方法。您应该修复from
子句以明确join
:
from wp_posts p join
wp_postmeta pm
on p.ID = pm.post_id
where p.post_type = 'shop_order' and p.post_status = 'wc-completed'
组合帖子数据的方法使用聚合。 join
方法如下:
select p.*,
pm_be.meta_value as billing_email,
pm_fn.meta_value as billing_first_name,
from wp_posts p left join
wp_postmeta pm_be
on p.ID = pm_be.post_id and pm_be.meta_key = '_billing_email' left join
wp_postmeta pm_fn
on p.ID = pm_fn.post_id and pm_fn.meta_key = '_billing_first_name' left join
. . .
where p.post_type = 'shop_order' and p.post_status = 'wc-completed'
如果性能是一个问题,那么值得尝试这两种方法。它们并不完全相同。
首先,聚合方法(您的方法)每个帖子只生成一行,而不管可能具有相同键值的值的数量。您可以使用group_concat()
而不是max()
来获取所有值。
这是一个优点,因为join
方法会为给定的密钥返回多行,而这通常不是您想要的。你可以使用group by
绕过它,但这会产生开销。
假设索引设置正确,join
方法通常会更快地从表中获取少量列。聚合方法的一个优点是添加新密钥基本上不会增加任何开销 - 实际上聚合已经非常昂贵,以至于额外的max()
或listagg()
不会增加很多。
无论采用哪种方法,都应该遵循一条简单的规则:从不在FROM
子句中使用逗号。 始终使用带有JOIN
子句的显式ON
语法。
答案 1 :(得分:0)
尝试使用此功能(使用加入)
select p.ID as order_id,
p.post_date,
max(CASE WHEN pm.meta_key = '_billing_email' THEN pm.meta_value END) as billing_email,
max(CASE WHEN pm.meta_key = '_billing_first_name' THEN pm.meta_value END) as _billing_first_name,
max(CASE WHEN pm.meta_key = '_billing_last_name' THEN pm.meta_value END) as _billing_last_name,
max(CASE WHEN pm.meta_key = '_order_total' THEN pm.meta_value END) as order_total,
max(CASE WHEN pm.meta_key = '_order_tax' THEN pm.meta_value END) as order_tax,
max(CASE WHEN pm.meta_key = '_paid_date' THEN pm.meta_value END) as paid_date
from wp_posts as p join
wp_postmeta as pm on (p.ID = pm.post_id)
where post_type = 'shop_order'and
and post_status = 'wc-completed'
group by p.ID
你可能需要用max(p.post_date)替换p.post_date
select p.ID as order_id,
max(p.post_date),
max(CASE WHEN pm.meta_key = '_billing_email' THEN pm.meta_value END) as billing_email,
max(CASE WHEN pm.meta_key = '_billing_first_name' THEN pm.meta_value END) as _billing_first_name,
max(CASE WHEN pm.meta_key = '_billing_last_name' THEN pm.meta_value END) as _billing_last_name,
max(CASE WHEN pm.meta_key = '_order_total' THEN pm.meta_value END) as order_total,
max(CASE WHEN pm.meta_key = '_order_tax' THEN pm.meta_value END) as order_tax,
max(CASE WHEN pm.meta_key = '_paid_date' THEN pm.meta_value END) as paid_date
from wp_posts as p join
wp_postmeta as pm on (p.ID = pm.post_id)
where post_type = 'shop_order'and
and post_status = 'wc-completed'
group by p.ID