【问题标题】:sql to find row for min date in each monthsql查找每个月最小日期的行
【发布时间】:2012-11-11 05:40:45
【问题描述】:

我有一张桌子,让我们说“记录”的结构:

id      date
--      ----
1       2012-08-30
2       2012-08-29
3       2012-07-25

我需要在 PostgreSQL 中编写一个 SQL 查询来获取每个月 MIN 日期的 record_id。

month    record_id
-----    ---------
8           2
7           3

我们看到 2012-08-29

我试过这样的,

SELECT
   EXTRACT(MONTH FROM date) as month,
   record_id,
   MIN(date) 
FROM Records
GROUP BY 1,2

但它显示了 3 条记录。

有人可以帮忙吗?

【问题讨论】:

    标签: sql postgresql min


    【解决方案1】:

    SQL Fiddle

    select distinct on (date_trunc('month', date))
        date_trunc('month', date) as month,
        id,
        date
    from records
    order by 1, 3 desc
    

    【讨论】:

      【解决方案2】:

      如果您有重复的最短日期,这将返回倍数:

      Select
        minbymonth.Month,
        r.record_id
      From (
        Select
          Extract(Month From date) As Month, 
          Min(date) As Date
        From
          records
        Group By 
          Extract(Month From date)
        ) minbymonth
          Inner Join
        records r
          On minbymonth.date = r.date
      Order By
        1;
      

      或者如果你有 CTE

      With MinByMonth As (
        Select
          Extract(Month From date) As Month, 
          Min(date) As Date
        From
          records
        Group By 
          Extract(Month From date)
        )
      Select
        m.Month,
        r.record_id
      From
        MinByMonth m
          Inner Join
        Records r
          On m.date = r.date
      Order By
        1;
      

      http://sqlfiddle.com/#!1/2a054/3

      【讨论】:

      • 这显然是要走的路。为了清楚起见,我会将子查询放置为 CTE(例如 WITH minbymonth AS ( ... your query ... ) SELECT。不过,这只是个人喜好问题。+1
      • @Thilo 好电话,也添加了这个。
      【解决方案3】:
      SELECT DISTINCT ON (EXTRACT(MONTH FROM date))
         id,
         date
      FROM Records1
      ORDER BY EXTRACT(MONTH FROM date),date
      

      SQLFiddle http://sqlfiddle.com/#!12/76ca2/3

      UPD:这个查询:

      1) 按月份和日期对记录进行排序

      2) 为每个月挑选第一条记录(第一条记录有MIN(date)因为排序)

      详情看这里http://www.postgresql.org/docs/current/static/sql-select.html#SQL-DISTINCT

      【讨论】:

      • 嗯。但是如何选择每个月的 MIN 日期呢?
      • @Kirill Reva 修复了查询
      【解决方案4】:

      我认为您需要使用子查询,如下所示:

      SELECT
         EXTRACT(MONTH FROM r.date) as month,
         r.record_id 
      FROM Records as r
      INNER JOIN (
          SELECT
             EXTRACT(MONTH FROM date) as month,
             MIN(date) as mindate
          FROM Records
          GROUP BY EXTRACT(MONTH FROM date)
      ) as sub on EXTRACT(MONTH FROM r.date) = sub.month and r.date = sub.mindate
      

      【讨论】:

      • 谢谢,这就是解决方案。
      【解决方案5】:
      select extract(month from date) 
      , record_id
      , date
      from
      (
          select
              record_id
             , date
             , rank() over (partition by extract(month from date) order by date asc) r
          from records
      ) x
      where r=1
      order by date
      

      【讨论】:

      • ps。如果在给定月份中有重复的最小日期时您想要一个结果,请将 rank() 更改为 row_number()。或者将 order by date asc 更改为 order by date asc, order by record_id asc 以在最小日期重复时获取具有较低 id 的记录。
      猜你喜欢
      • 2016-09-02
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 2014-07-04
      • 1970-01-01
      • 2020-10-30
      • 2019-06-23
      • 1970-01-01
      相关资源
      最近更新 更多