2015-04-05 81 views
0

我已經創建了下面的查詢:加入的ID或空並獲得第一個結果

select * from store str 
left join(
    select * from schedule sdl 
    where day = 3 
    order by 
    case when sdl.store_id is null then (
    case when sdl.strong is true then 0 else 2 end 
    ) else 1 end, sdl.schedule_id desc 
) ovr on (ovr.store_id = str.store_id OR ovr.store_id IS NULL) 

的樣本數據:

STORE 
[store_id] [title] 
20010  Shoes-Shop 
20330  Candy-Shop 

[SCHEDULE] 
[schedule_id] [store_id] [day] [strong] [some_other_data] 
1    20330  3  f  10% Discount 
2    NULL  3  t  0% Discount 

我想從LEFT JOIN獲得對於兩種數據NULL store_id(全局計劃條目 - 影響所有商店條目)或給定store_id的實際數據。

像這樣加入查詢,返回結果的正確順序,但是對於NULL和store_id匹配。使用連接子句上的OR語句是有意義的。

預期的結果:

[store_id] [title]  [some_other_data] 
20010  Shoes-Shop 0% Discount 
20330  Candy-Shop 0% Discount 

當前結果:

[store_id] [title]  [some_other_data] 
20010  Shoes-Shop 0% Discount 
20330  Candy-Shop 0% Discount 
20330  Candy-Shop 10% Discount 

如果有關於這個問題的更好的方法我很高興能跟隨它。

+0

Thetable定義('\ d tbl'在psql中),你的Postgres版本是in的核心部分形成這樣的問題。和演示數據,實際顯示案件你想要的。 – 2015-04-06 02:06:19

回答

0

DISTINCT ON應該工作得很好,只要你得到ORDER BY權利。基本上,在schedulestrong = TRUE匹配優先,然後用store_id IS NOT NULL匹配:

SELECT DISTINCT ON (st.store_id) 
     st.store_id, st.title, sl.some_other_data 
FROM store   st 
LEFT JOIN schedule sl ON sl.day = 3 
         AND (sl.store_id = st.store_id OR sl.store_id IS NULL) 
ORDER BY NOT strong, store_id IS NULL; 

這樣做是因爲:

基礎知識DISTINCT ON

替代了LATERAL加入(Postgres的9.3+):

SELECT * 
FROM store st 
LEFT JOIN LATERAL (
    SELECT some_other_data 
    FROM schedule 
    WHERE day = 3 
    AND (store_id = st.store_id OR store_id IS NULL) 
    ORDER BY NOT strong 
     , store_id IS NULL 
    LIMIT 1 
    ) sl ON true; 

關於LATERAL加入:

+0

謝謝歐文。加入Lateral是我正在尋找的。 9.2.7是否支持側向連接? – mallix 2015-04-06 12:26:06

+0

@mallix:沒有。我添加了一個鏈接。 – 2015-04-06 12:56:16

+0

不同的技巧,但與我的訂單混亂。我在這裏發佈的查詢只是實際查詢的一小部分,所以我會去升級和聯合側面。 – mallix 2015-04-06 14:54:44

1

我認爲最簡單的做法是使用distinct on。接下來的問題是你如何訂購它:

select distinct on (str.store_id) * 
from store str left join 
    schedule sdl 
    on (sdl.store_id = str.store_id or sdl.store_id is null) and dl.day = 3 
order by str.store_id, 
     (case when sdl.store_id is null then 2 else 1 end) 

這將如果可用返回store備案,否則具有的NULL的值schedule記錄。注意:您的查詢有這個概念strength,但這個問題沒有解釋如何使用它。這可以很容易地修改,以包括多個優先級別。

+0

獨特的不幫。讓我解釋。我有一套固定折扣店。每個商店可能會覆蓋設置(計劃)。覆蓋有3個優先級:全局覆蓋強(store_id NULL,強TRUE),普通存儲覆蓋(store_id),全局覆蓋弱(store_id NULL,強假)。所以同一家商店可能落入全球和正常。如果我選擇正常,我會選擇全球。但是我當前的查詢返回3條記錄而不是2.如果我限制1,我將失去其他商店的全局功能。 – mallix 2015-04-05 21:53:36

+0

@mallix。 。 。根據'order by'中設置的優先級,'distinct on'應該爲每個商店返回一個值。這看起來像你想要做的。 – 2015-04-06 00:36:27