2015-04-05 78 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