我有一个ids的列表:

select id from id where sid = 2403

上面只返回一个id的列表.例如id = 401434786、401434787、401434788等.

当我在tval表中运行其中一个id时,我得到:

select * from tval where id = 401434786;

我得到:

   id        fid                ts                  val
401434786   3765    2019-05-14 00:00:00.000 2019-11-18 00:00:00.000
401434786   3771    2019-11-18 00:00:00.000 2019-11-18 00:00:00.000
401434786   3782    2019-05-14 00:00:00.000 2019-11-18 00:00:00.000 

我的目标是过滤id的列表,只有fid = 3771fid = 3782valNOT相同的那些.

我有一个查询,它做:

select distinct t.id from tval t 
where (select min(t1.val) from tval t1 
         where t1.id = t.id and t1.fid = 3771)
    !=(select min(t1.val) from tval t1 
         where t1.id = t.id and t1.fid = 3782)
  and id in (select id from id where sid = 2403); 

然而,我想修改查询,或者写一个全新的查询,以过滤id的列表,其中只有MonthYear是不同的,但如果MonthYear是相同的,但Day是不同的,然后删除它.

在上面的查询中,它过滤id,如果MonthYear相同,但Day不同,它仍然将其包含在输出中,但我不希望这样.我只想要MonthYear不同的id.

我希望上面的内容是有意义的,我真的很感激任何帮助!

推荐答案

使用date_trunc().将两个日期/时间戳截断为一个月后,只要它们的年份和月份匹配,它们就变成等效的:

select distinct t.id from tval t 
where (select min(date_trunc('month',t1.val)) from tval t1 
         where t1.id = t.id and t1.fid = 3771)
    !=(select min(date_trunc('month',t1.val)) from tval t1 
         where t1.id = t.id and t1.fid = 3782)
  and id in (select id from id where sid = 2403); 

这种比较不仅有效地忽略了日期,而且忽略了低于一个月精度的任何东西,也忽略了天、小时、分钟、秒和分数.

如果min()是某种妥协,而你实际上想避免ids在同一个月有任何一对3771和3782(而不仅仅是在给定的id的最早出现时),你可以使用array overlap &&:

select distinct t.id from tval t 
where not 
      (select array_agg(date_trunc('month',t1.val)) from tval t1 
         where t1.id = t.id and t1.fid = 3771)
    &&(select array_agg(date_trunc('month',t1.val)) from tval t1 
         where t1.id = t.id and t1.fid = 3782)
  and id in (select id from id where sid = 2403); 

这可能会比not exists更快:

select distinct t.id from tval t 
where not exists
      (select from tval t1 where t1.id = t.id and t1.fid = 3771
       where date_trunc('month',t1.val) in 
          ( select date_trunc('month',t1.val) from tval t1 
            where t1.id = t.id and t1.fid = 3782) )
  and id in (select id from id where sid = 2403); 

Sql相关问答推荐

查询多个表并返回合并在联合列上的所有表中的所有行

更新在两个或多个面中具有交点的面

如果开始期间不存在PostgresSql回填数据

为表中每个缺少的引用创建新行

如何嵌套两条SQL语句

如何查找所提供日期范围的所有季度开始日期和结束日期

查找表中特定值的上次更新日期

NULL-生成的列中连接的字符串的输入

从数据库中查找总和大于或等于查询中的数字的数字

我可以在SQLite3中使用BLOB作为主键吗?

使用SQL数据库中的现有列派生或修改几个列

使用特定的Order By子句随机化SQL输出

SQL OR子句如何在JOINON查询中工作?

达到特定值时,从0开始累加求和

IN子句使用的表值用户定义函数参数

使用ALTER TABLE无法删除列

Select 多年的日期范围

过滤具有一对多关系的两个表之间的数据

SQL - 使用子查询返回多行的 LIKE 命令

在 Microsoft SQL Server 中,如何只为特定值保留不同的行?