繁体   English   中英

MySQL Select查询-用例何时或加入?

[英]MySQL Select Query - Use Case When or Join?

我有一个简单的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重写它的示例,因为我可能会以错误的方式进行操作。

在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子句中使用逗号。 始终使用带有ON子句的显式JOIN语法。

尝试使用它(使用连接)

   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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM