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

时间:2018-01-03 12:04:51

标签: sql sql-server date datetime

假设我有这样的数据:

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

有人可以帮忙吗?感谢

3 个答案:

答案 0 :(得分:1)

使用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;

答案 1 :(得分: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

答案 2 :(得分:0)

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

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

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)
;