2016-08-07 24 views
0

我有一個簡單的SELECT語句如下:MySQL Select Query - 使用案例時還是加入?

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

您正在調整數據。爲了旋轉'條件聚合'(你的當前方法)是相當合理的。不知道是誰建議你使用'Join'來轉發數據。只有我發現可以改進你的查詢是使用'INNER JOIN'語法來加入兩個表,而不是使用'逗號分隔連接' –

+0

你想做什麼? –

回答

1

基本上有在旋轉數據兩種方法來代替p.post_date 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子句。

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 

您可能需要最多(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