【问题标题】:SQL Query to return all rows with the earliest date available for each yearSQL 查询以返回每年可用的最早日期的所有行
【发布时间】:2020-10-02 10:27:09
【问题描述】:

我正在尝试设计一个可以返回每年最早日期的记录的 SQL 查询。假设我有一个如下表:

Date       | Category | Value
========== | ======== | =====
2019-01-03 | Apple    | 5
2019-01-03 | Orange   | 2
2019-01-20 | Apple    | 5
2019-01-20 | Orange   | 8
2019-02-05 | Apple    | 1
2019-02-05 | Peach    | 5
2018-01-02 | Apple    | 2
2018-01-02 | Orange   | 9
2018-05-10 | Apple    | 3
2018-05-10 | Orange   | 5
2018-07-20 | Apple    | 6
2018-07-20 | Orange   | 1

我正在尝试生成如下所示的表格:

Date       | Category | Value
========== | ======== | =====
2019-01-03 | Apple    | 5
2019-01-03 | Orange   | 2
2018-01-02 | Apple    | 2
2018-01-02 | Orange   | 9

每年的最早日期会发生变化,这意味着我不能简单地按日和月查询。我试过使用:

SELECT MIN(Date), * 
FROM mytable 
GROUPBY YEAR(Date)

但这会导致聚合错误:“类别”在选择列表中无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中

实现这一目标的最佳方法是什么?

【问题讨论】:

  • 您实际使用的是哪些 rdms?
  • 我的数据库在 Microsoft SQL Server 中运行

标签: sql sql-server date


【解决方案1】:

一种简单的方法是关联子查询:

select t.*
from mytable t
where t.date = (select min(t2.date)
                from mytable t2
                where t2.category = t.category and year(t2.date) = year(t.date)
               );

你也可以使用row_number():

select t.*
from (select t.*,
             row_number() over (partition by category, year(date) order by date) as seqnum
      from mytable t
     ) t
where seqnum = 1

【讨论】:

    【解决方案2】:

    这是一种可能

    CREATE TABLE mytable  (
      [Date] VARCHAR(10),
      [Category] VARCHAR(6),
      [Value] INTEGER
    );
    
    INSERT INTO mytable 
      ([Date], [Category], [Value])
    VALUES
      ('2019-01-03', 'Apple', '5'),
      ('2019-01-03', 'Orange', '2'),
      ('2019-01-20', 'Apple', '5'),
      ('2019-01-20', 'Orange', '8'),
      ('2019-02-05', 'Apple', '1'),
      ('2019-02-05', 'Peach', '5'),
      ('2018-01-02', 'Apple', '2'),
      ('2018-01-02', 'Orange', '9'),
      ('2018-05-10', 'Apple', '3'),
      ('2018-05-10', 'Orange', '5'),
      ('2018-07-20', 'Apple', '6'),
      ('2018-07-20', 'Orange', '1');
    GO
    
    12 行受影响
    SELECT t1.*
    FROM mytable t1 INNER JOIN
    (SELECT MIN([Date]) mindate,[Category]
    FROM mytable
    GROUP BY 
    [Category], YEAR([Date])) t2
    ON t1.[Category] = t2.[Category] AND t1.[Date] = t2.mindate
    ;
    GO
    
    日期 |类别 |价值 :--------- | :------- | ----: 2019-01-03 |苹果 | 5 2019-01-03 |橙色 | 2 2019-02-05 |桃子 | 5 2018-01-02 |苹果 | 2 2018-01-02 |橙色 | 9

    db小提琴here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-03
      • 2010-10-21
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 2014-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多