当到期日总是在每个月的最后一天时,查找唯一ID

时间:2018-07-13 19:09:55

标签: sql distinct

我必须在每个ID的整个历史中找到不同的ID,其到期日总是在每个月的最后一天。
假设我有以下数据集:

  ID  DUE_DT
  1   1/31/2014
  1   2/28/2014
  1   3/31/2014
  1   6/30/2014
  2   1/30/2014
  2   2/28/2014
  3   1/29/2016
  3   2/29/2016

我想用SQL编写代码,以便它给我ID = 1,因为特定的ID到期日总是在每个给定月份的最后一天。

最简单的方法是什么?

4 个答案:

答案 0 :(得分:0)

MySQL-版本(提供@Gordon Linoff的信用)

SELECT
    ID
FROM
    <table>
GROUP BY
    ID
HAVING
    SUM(IF(day(DUE_DT + interval 1 Day) = 1, 1, 0)) = COUNT(ID);

原始答案:

SELECT MAX(DUE_DT) FROM <table> WHERE ID = <the desired ID>

或者如果您希望每个唯一ID都具有MAX(DUE_DT)

SELECT ID, MAX(DATE) FROM <table> GROUP BY ID

答案 1 :(得分:0)

您可以这样做:

select id
from t
group by id
having sum(case when extract(day from due_dt + interval '1 day') = 1 then 1 else 0 end) = count(*);

这使用ANSI / ISO标准函数进行日期运算。这些值随数据库的不同而有所不同,但是在所有数据库中,想法都是一样的-添加一天,然后查看所有行的月份是否为1。

答案 2 :(得分:0)

如果您使用的是SQL Server 2012+,则可以使用EOMONTH()函数来实现:

SELECT DISTINCT ID FROM [table]
WHERE DUE_DT = EOMONTH(DUE_DT)

http://rextester.com/VSPQR78701

答案 3 :(得分:0)

这个想法很简单:

  • 如果(到期日的月份)与(到期日的月份+ 1天)不同,则您在该月的最后一天。这涵盖了跨年,year年等的所有情况。
  • 从那里开始,如果(一个ID的行数)与(该ID的行数是一个月的最后一天)相同,那么您就有赢家了。

我试图写一个例子(未经测试)。您没有指定哪个数据库,所以我假设cte(公用表表达式)可用。如果不是,只需将cte作为子查询即可。 同样,我不确定dateaddinterval在所有方言中的工作方式是否相同。

with addlastdayofmonth as (
select
    id
    -- adding a 'virtualcolumn', 1 if last day of month 0 otherwise
  , if(month(dateadd(due_date, interval '1' day)) != month(due_date), 1 ,0) as onlastday
from
  table
)
select 
    id
  , count(*) - sum(onlastday) as alwayslastday 
from
  addlastdayofmonth
group by
  id
having
  -- if count(rows) == count(rows with last day) we have a winner
  halwayslastday = 0