SQL选择记录,除非类型是特定种类,先前或与日期

时间:2018-02-01 01:53:15

标签: sql teradata

尝试选择所有记录,除非类型较小且与相同的id之前或相同的日期

id  date    type
1   02/09/2012  BIG
2   05/16/2012  BIG
2   06/18/2012  BIG
3   08/08/2011  BIG
3   09/13/2011  BIG
4   06/08/2016  BIG
4   05/27/2016  SMALL
5   08/16/2012  BIG
5   08/15/2012  SMALL
6   09/05/2012  BIG
7   09/05/2012  BIG
7   02/13/2013  BIG
7   08/03/2011  BIG
7   05/09/2012  BIG
7   04/24/2013  SMALL
8   03/31/2017  BIG
8   03/06/2017  SMALL
9   02/17/2016  SMALL

我尝试的代码

select id, date, type
from (select id, date,type,   min(case when type = 'SMALL' then date end) 
over (partition by id) as min_dt
from table1 as t ) t
where date>min_dt
group by 1,2,3

这只给了我这些记录

id  date    type    
4   06/08/2016  BIG
5   08/16/2012  BIG
8   3/31/2017   BIG

但这些是我期待的一次

id  date    type    
1   2/9/2012    BIG 
2   5/16/2012   BIG 
2   6/18/2012   BIG 
3   8/8/2011    BIG 
3   9/13/2011   BIG 
4   6/8/2016    BIG 
4   5/27/2016   SMALL   X
5   8/16/2012   BIG 
5   8/15/2012   SMALL   X
6   9/5/2012    BIG 
7   9/5/2012    BIG 
7   2/13/2013   BIG 
7   8/3/2011    BIG 
7   5/9/2012    BIG 
7   4/24/2013   SMALL   
8   3/31/2017   BIG 
8   3/6/2017    SMALL   X
9   2/17/2016   SMALL   

期待除了错误之外的一切

3 个答案:

答案 0 :(得分:1)

这是一种方法:

select t1.*
from table1 t1
where t1.type <> 'SMALL' or
      exists (select 1
              from table1 tt1
              where tt1.id = t1.id and tt1.date < t1.date
             );

答案 1 :(得分:1)

Select id, date, type from table1 t
Where type <> ‘SMALL’ or 
not exists(select date from table1 
where id = t.id and date >= t.date and type <> 'SMALL')

修改

根据OP的声明,我们将获取除

之外的所有记录

1。 类型很小

2。 与相同ID 之前或同一日期
(我认为这个日期小于或等于至少1个具有相同id的其他记录)

都是真的,

意味着我们将获得至少有一个条件为假的记录。

因此type <> ‘SMALL’获取第一个条件为假的记录

or not exists(select date from table1 
    where id = t.id and date >= t.date and type <> 'SMALL')

获取第二个条件为假的记录,例如。其中没有记录具有相同的id,数据小于或等于

答案 2 :(得分:1)

这适用与@AnthonyMcGrath解决方案相同的逻辑,但使用OLAP函数:如果另一行&lt;&gt;,则检查SMALL行(使用总计)。存在较小或相等日期的SMALL并将其丢弃。

SELECT *
FROM table1
QUALIFY 
   type <> 'SMALL' -- all other rows
OR -- it's SMALL
   Min(CASE WHEN type <> 'SMALL' THEN date END) -- returns NULL if there's no later row
   Over (PARTITION BY id
         ORDER BY date DESC
           ,CASE WHEN type <> 'SMALL' THEN 0 ELSE 1 END -- same date-> ensure SMALL is sorted last
         ROWS Unbounded Preceding) IS NULL

将你的逻辑改为&#34;只有当它是最新的一行时才返回一个小行#34; 似乎也适用于ROW_NUMBER:

QUALIFY type_ <> 'SMALL'
  OR Row_Number() -- get the latest row if it's SMALL
     Over (PARTITION BY id
           ORDER BY date DESC
             ,CASE WHEN type <> 'SMALL' THEN 0 ELSE 1 end) = 1