【问题标题】:Find last (first) instance in table but exclude most recent (oldest) date在表中查找最后一个(第一个)实例,但排除最近(最旧)日期
【发布时间】:2012-10-15 20:50:34
【问题描述】:

我有一张表格,可以反映某个人口的每月人口普查。每个月在该月初的一个不可预测的日子,都会对人口进行民意调查。在那个时候存在的任何成员都包含在该月的民意调查中,任何不存在的成员都不是。

我的任务是查看任意日期范围并确定在该时间段内添加或丢失了哪些成员。考虑样本表:

ID | Date
2  | 1/3/2010
3  | 1/3/2010
1  | 2/5/2010
2  | 2/5/2010
3  | 2/5/2010
1  | 3/3/2010
3  | 3/3/2010

在这种情况下,ID 为“1”的成员在 1 月至 2 月之间添加,ID 为 2 的成员在 2 月至 3 月之间丢失。

我遇到的问题是,如果我只是轮询尝试查找最新条目,我将捕获所有已删除的成员,以及最后日期存在的所有成员。例如,我可以运行以下查询:

SELECT
  ID,
  Max(Date)
FROM
  tableName
WHERE
  Date BETWEEN '1/1/2010' AND '3/27/2010'
GROUP BY
  ID

这将返回:

ID  | Date
1   | 3/3/2010
2   | 2/5/2010
3   | 3/3/2010

然而,我真正想要的只是:

ID  | Date
2   | 2/5/2010

当然我可以手动过滤掉最后一个日期,但由于开始和结束日期是参数,我想概括一下。一种方法是运行顺序查询。在第一个查询中,我会找到最后一个日期,然后在第二个查询中使用它来过滤。但是,如果我可以将此逻辑包装到单个查询中,那将真的很有帮助。

当我尝试查找成员首次添加到人口中时,我也遇到了相关问题。在这种情况下,我使用的是不同类型的查询:

SELECT
  ID,
  Date
FROM
  tableName i
WHERE
  Date BETWEEN '1/1/2010' AND '3/27/2010'
 AND
  NOT EXISTS(
    SELECT
      ID,
      Date
    FROM
      tableName ii
    WHERE
      ii.ID=i.ID
     AND
      ii.Date < i.Date
     AND
      Date BETWEEN '1/1/2010' AND '3/27/2010'
  )

这会返回:

ID  | Date
1   | 2/5/2010
2   | 1/1/2010
3   | 1/1/2010

但我想要的是:

ID  | Date
1   | 2/5/2010

我想知道: 1. 哪种方法(MAX() 或 NOT EXISTS 的子查询)更有效且 2. 如何修复查询,使它们只返回我想要的行,不包括第一个(最后一个)日期。

谢谢!

【问题讨论】:

  • 什么种类的SQL? MySQL 比 PostGreSQL、Oracle、SQL Server 等更受限制。对于某些操作,它们都有不同的语法。
  • 我需要能够在各种 RDBMS 中工作的东西,至少包括 Teradata 和 DB2。可能更多。 (我是新职位,还不了解我们所有的系统。)

标签: sql


【解决方案1】:

你可以这样做:

SELECT
  ID,
  Max(Date)
FROM
  tableName
WHERE
  Date BETWEEN '1/1/2010' AND '3/27/2010'
GROUP BY
  ID
having max(date) < '3/1/2010'

这会过滤掉 3 月份接受调查的任何人。

【讨论】:

  • 这太棒了。我曾尝试使用类似的东西(使用具有差异的子句),但它不起作用。你能权衡一下效率问题吗?使用 max() 的方法与子查询方法相比,看起来真的很容易理解/编写,但是有没有效率成本?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-13
  • 1970-01-01
  • 2014-03-12
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 2018-01-30
相关资源
最近更新 更多