SQL从同一列中选择最小日期

时间:2014-07-31 18:24:36

标签: sql date record min

我正在尝试根据帐户及其合同编写查询。该表包含每个帐户的所有合同,无论合同是否有效,是否已过期等。我希望查询仅以每个帐户的最早开始日期恢复合同,因此每个帐户只有一行。但是,我不知道每个帐户最早的合同的状态。有些可能有效,有些可能有待处理。我现在遇到问题,如果合同状态在我指定的列表中,它会为每个帐户带回多个记录。简单的示例代码如下:

Select t.account, t.contract, t.status Min(t.start_date)
From table t
where t.status in ('Active','Countersigned','Pending')

3 个答案:

答案 0 :(得分:1)

如果您的数据库支持它(例如Oracle,Postgres,SQL Server,但不支持MySQL或SQLite),则可以使用Window Functions。例如,您可以通过starting_at:

在每个帐户中对合同进行排名
SELECT *, rank() OVER (PARTITION BY account_id ORDER BY starting_at ASC) AS rank
FROM   contracts

然后你可以在子查询中使用它来加入帐户并只获取等级为1的合同。你需要将它放在子查询中,因为不幸的是(至少在Postgres中)你 不能在WHERE中使用窗口函数。所以这不会起作用:

SELECT *, rank() OVER (PARTITION BY account_id ORDER BY starting_at ASC) AS rank
FROM   contracts
WHERE  rank = 1

但这会:

SELECT *
FROM (SELECT *, rank() OVER (PARTITION BY account_id ORDER BY starting_at ASC) AS rank
      FROM   contracts) x
WHERE rank = 1

请注意,您可以轻松地按状态等添加过滤到任何这些查询。

答案 1 :(得分:0)

如果您在同一个MIN(date)上没有为每个帐户签订多个合同,那么该解决方案有效(在这种情况下,您可以为每个帐户获取多行,并且您应该决定这些中的哪一个您希望看到的N份合约,我无法为您做出决定)

SELECT t.*
FROM (
    Select t.account, Min(t.start_date) AS MinDate
    From table t
    where t.status in ('Active','Countersigned','Pending')
    GROUP BY t.account
) AS t2
INNER JOIN table t ON t.account = t2.account AND t.start_date = t2.MinDate 

答案 2 :(得分:0)

这应该有效:

select account, contract, status, MinDate
from
(
Select t.account, t.contract, t.status, t.start_date,
Min(t.start_date) over(partition by t.account) MinDate
From table t
where t.status in ('Active','Countersigned','Pending')
) x
where start_date=MinDate