2017-03-14 69 views
0

我有一个postgres表fetches下面列基础上多列选择唯一的记录检查

id | status | company_id | created_at 
------------------------------------------- 
10 | success | 2773  | 2017-03-14 
11 | error | 190   | 2017-03-02 
12 | error | 303   | 2017-03-01 
13 | error | 286   | 2017-02-16 
14 | error | 2773  | 2016-12-05 

我想达到以下结果:

id | status | company_id | created_at 
------------------------------------------- 
11 | error | 190   | 2017-03-02 
12 | error | 303   | 2017-03-01 
13 | error | 286   | 2017-02-16 

这是我想的逻辑适用于:

  1. 获取所有提取的状态为error
  2. 如果结果包含任何company_id,其最新的fetch(由created_at)为success然后从最终结果集中跳过它。
  3. company_id = 2773将被跳过,因为它是最新的获取状态是success

请告知我如何在SQL的方式做到这一点。

+0

当你改变你想达到的目标,请将其标记为更新。现在你有3个工作方法,每个都在做你说的你需要的东西,但是你的新定义废弃了所有的三个... –

+0

我会确保这么做!并更新这一个!但是#3和#2点都指向我之前说过的,但是以更详细的方式。 –

回答

1

尝试外连接:

with succ as (select company_id from fetches where status = 'success') 
select fetches.* 
from fetches 
left outer join succ on succ.company_id = fetches.company_id 
where succ.company_id is null; 
+0

本地花费了10246 ms。请注意,我们在db中有更多的“成功”提取和很少的“错误”提取。所以,我认为采取其他方式应该可以做到这一点。你说什么,@ vao-tsun? –

+0

如果你不想比较表本身,使用窗口函数,作为@戈登Linoff建议 –

0

看来你需要一个有状态没有更迭

select * from my_table 
where company_id not in (select company_id from my_table where status = 'success') 
1

您可以使用窗口功能,这为公司行:

select f.* 
from (select f.*, 
      sum((status = 'success')::int) over (partition by company_id) as isSuccess 
     fetches f 
    ) f 
where isSuccess = 0 and status = 'error'; 
+0

查询证明是耗时的,只是为了获取几行它采取'10169 ms' –

+0

也似乎它没有检查点#2和#3 –