简体   繁体   English

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

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

I have a simple Select statement as follows: 我有一个简单的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

It's been suggested that I should use the JOIN syntax - I assume instead of CASE WHEN. 有人建议我应该使用JOIN语法-我假设使用的不是CASE WHEN。 I've started working on a JOIN version but it doesn't appear to be less verbose so far - just wondering if this is indeed best practise and more efficient to process etc? 我已经开始研究JOIN版本,但到目前为止,它似乎还不那么冗长-只是想知道这是否确实是最佳实践,并且处理效率更高?

I'm new to SQL and learning as I go so would love to see examples of how this could be rewritten using JOIN as I might be going about this the wrong way. 我是SQL的新手,我正在学习,所以很想看看如何使用JOIN重写它的示例,因为我可能会以错误的方式进行操作。

There are basically two methods for pivoting data in MySQL. 在MySQL中,基本上有两种数据透视方法。 You should fix your from clause to have an explicit join : 您应该修复您的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'

Your method for combining the data about a post uses aggregation. 您用于合并有关帖子数据的方法使用汇总。 The join method looks like: 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'

If performance is an issue, then it is worth trying both methods. 如果性能是一个问题,那么值得尝试两种方法。 They are not exactly the same. 它们并不完全相同。

First, the aggregation method (your method) produces exactly one row per post, regardless of the number of values that might have the same key value. 首先,聚合方法(您的方法)每个帖子仅产生一行,而与可能具有相同键值的值的数量无关。 You can get all the values using group_concat() rather than max() . 您可以使用group_concat()而不是max()获得所有值。

This is an advantage, because the join method would return multiple rows for a given key, and that is generally not what you want. 这是一个优点,因为join方法将为给定的键返回多个行,而这通常不是您想要的。 You can get around it using a group by , but that incurs overhead. 您可以使用group by解决它,但这会产生开销。

The join method is typically going to be faster for getting a handful of columns from the table -- assuming indexes are set up correctly. 假设索引设置正确, join方法通常会更快地从表中获取少数列。 One advantage of the aggregation method is that adding new keys is basically adds no overhead -- essentially the aggregation is already so expensive that an additional max() or listagg() doesn't add very much. 聚合方法的一个优点是,添加新键基本上不会增加​​开销-本质上,聚合已经非常昂贵,以至于额外的max()listagg()不会增加太多。

Regardless of the method, there is one simple rule you should follow: Never use commas in the FROM clause. 无论使用哪种方法,都应遵循一个简单的规则: 切勿FROM子句中使用逗号。 Always use explicit JOIN syntax with an ON clause. 始终使用带有ON子句的显式JOIN语法。

Try to use this (using 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

you might need to replace p.post_date by max(p.post_date) 您可能需要用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