查询搜索2年并排除1

时间:2016-03-23 14:01:49

标签: sql teradata

我为这个措辞奇怪的问题道歉,因为我不确定如何在不解释情况的情况下命名标题。

我目前正在使用供应商表,该表为每个供应商提供唯一的ID,但该表未规范化。

例如,ID 100000003744450在表格中多次出现,每行都有不同的数据。

有很多专栏,但目前对我来说唯一重要的是ID和年份专栏。我试图找到2013年,2014年而不是2015年的供应商。

到目前为止,我有:

select * 
from table
where ls_d_yr = '2013'
   or ls_d_yr = '2014'

我需要通过删除任何拥有2013/2014年度的任何供应商来过滤此结果,并且不应该列出2015年的任何行。

以下是专栏

enter image description here

enter image description here

5 个答案:

答案 0 :(得分:4)

如果是2013年和2014年之一,请使用NOT EXISTS在2015年排除拥有ls_d_yr的ID。

select * 
from table t1
where ls_d_yr IN ('2013', '2014')
  and not exists (select 1 from table t2
                  where t2.ID = t1.ID
                    and t2.ls_d_yr = '2015')

如果需要2013年和2014年,请添加GROUP BY并使用HAVING以确保提供两年不同年份:

select ID 
from table t1
where ls_d_yr IN ('2013', '2014')
  and not exists (select 1 from table t2
                  where t2.ID = t1.ID
                    and t2.ls_d_yr = '2015')
group by ID
having count(distinct ls_d_yr) = 2

答案 1 :(得分:2)

您可以使用NOT EXISTS

select * 
from table AS t1
where ls_d_yr IN ('2013', '2014') AND
      NOT EXISTS (SELECT 1
                  FROM table AS t2
                  WHERE t1.ID = t2.ID AND ls_d_yr = '2015')

答案 2 :(得分:2)

另一种变体应该适用于Teradata和Aster(可能还有其他每个DBMS):

select vendor
from table
where ls_d_yr in ('2013','2014','2015') -- probably numbers instead of strings?
group by vendor
having min(ls_d_yr) = '2013' -- at least one row from 2013
   and max(ls_d_yr) = '2014' -- at least one row from 2014, but none from 2015

答案 3 :(得分:1)

执行此操作的一种方法是使用聚合和having

select t.vendor
from table t
group by t.vendor
having sum(case when ls_d_yr = '2013' then 1 else 0 end) > 0 and
       sum(case when ls_d_yr = '2014' then 1 else 0 end) > 0 and
       sum(case when ls_d_yr = '2015' then 1 else 0 end) = 0;

having条款中的每个条件都会测试一年。 > 0表示该年份存在一个或多个记录。 = 0表示不存在记录。

这个逻辑基于以下声明:"我试图找到2013年,2014年而不是2015年的行的供应商。"我不遵循最后一段中的逻辑。

答案 4 :(得分:0)

select to_char(id), ls_d_yr 
  from table 
 where ls_d_yr like '%2014%' 
    or ls_d_yr like '%2013%';

类似的东西。