获取所有记录,每个月的最短日期,但最新的时间

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了获取所有记录,每个月的最短日期,但最新的时间相关的知识,希望对你有一定的参考价值。

假设我有这样的数据:

Date                    Category Amount
01/10/2014 20:04    2   12212
01/11/2014 0:00 3   11043.38
01/11/2014 16:03    2   12082
01/11/2014 16:32    3   110.43
01/12/2014 20:41    2   12196
01/12/2014 20:42    3   103.22
31/12/2014 14:20    2   12440
31/12/2014 14:21    3   104.25

我希望得到以下结果:

Date                   Category Amount
01/10/2014 20:04    2   12212
01/11/2014 16:03    2   12082
01/11/2014 16:32    3   110.43
01/12/2014 20:41    2   12196
01/12/2014 20:42    3   103.22

到目前为止,我能够进行此查询:

select t.date, t.Category, t.Amount
from mytable t
inner join (
    select Category,MONTH(date) MONTHH,YEAR(date) YEARR, max(date) as MaxDate
    from mytable
    group by Category,MONTH(date) MONTHH,YEAR(date) YEARR
) tm on t.date = tm.MaxDate and t.Category = tm.Category

但如果1个月内有超过1个日期,则会返回错误的结果。这是结果:

Date                   Category Amount
01/10/2014 20:04    2   12212
01/11/2014 16:03    2   12082
01/11/2014 16:32    3   110.43
31/12/2014 14:20    2   12440
31/12/2014 14:21    3   104.25

有人可以帮忙吗?谢谢

答案

使用row_number()rank()

select t.*
from (select t.*,
             dense_rank() over (partition by year(date), month(date) order by day(date)) as seqnum,
             row_number() over (partition by year(date), month(date), day(date) order by date desc) as seqnum_d
      from mytable t
     ) t
where seqnum = 1 and seqnum_d = 1;
另一答案

试试这个

;WITH CTE
AS
(
    SELECT
        RN = ROW_NUMBER() OVER(PARTITION BY MONTH([Date]),YEAR([Date]),Category ORDER BY [Date]),
        *
        FROM YourTable
)
SELECT
    Date,
Category,
Amount
        FROM CTE
            WHERE RN = 1
另一答案

不要将保留字用作列(即日期)。

无需分组,您没有使用任何求和/平均:

select * 
from tda  t
where not exists(
   -- not exists: same date, later time, cat is same
      select 1 
      from tda b
      where 1 = 1
        and cast(t.dDate as date) = cast(b.dDate as date) 
        and t.ddate > b.ddate 
        and t.cat = b.cat
)
and not exists(
      -- not exists: same month, earlier date 
      select 1 
      from tda b 
      where month(b.ddate) = month(t.ddate) 
      and day(b.ddate)<day(t.ddate)
)

得到(根据自己的喜好重新格式化日期):

ddate                   Cat Amount
2014-10-01T20:04:00Z    2   12212
2014-11-01T00:00:00Z    3   11043.38
2014-11-01T16:03:00Z    2   12082
2014-12-01T20:41:00Z    2   12196
2014-12-01T20:42:00Z    3   103.22

通过

CREATE TABLE tda  ([ddate] datetime,[Cat] int, [Amount] numeric(10,2));

INSERT INTO tda   (dDate,  Cat, Amount)
VALUES
    ('2014/10/01 20:04', 2, 12212),
    ('2014/11/01 0:00', 3, 11043.38),
    ('2014/11/01 16:03', 2, 12082),
    ('2014/11/01 16:32', 3, 110.43),
    ('2014/12/01 20:41', 2, 12196),
    ('2014/12/01 20:42', 3, 103.22),
    ('2014/12/31 14:20', 2, 12440),
    ('2014/12/31 14:21', 3, 104.25)
;

以上是关于获取所有记录,每个月的最短日期,但最新的时间的主要内容,如果未能解决你的问题,请参考以下文章

获取几个月的最新记录并使用 Oracle PL-SQL 为每个 ID 汇总其值

查看以获取条件复杂的最短日期

Python sqlite3 SQL查询获取具有最新日期但每个唯一列限制的所有条目

按最新日期获取分组后的列

获取从当前日期到下一个完整月的记录(直到下个月的最后一个日期)mysql [重复]

获取每个 id 的最新记录