【问题标题】:Returning rows where the WHERE clause was not an exact match返回 WHERE 子句不完全匹配的行
【发布时间】:2018-12-04 16:22:23
【问题描述】:

我提前为问题标题道歉。我真的很难写出简洁的东西!

我有一个类似于以下的表格:

| Item    | Date       | Value |
| A       | 2018-12-01 | 1     |
| B       | 2018-12-01 | 2     |
| C       | 2018-12-01 | 2     |
| A       | 2018-12-02 | 3     |
| B       | 2018-12-02 | 3     |

我想写一个查询,这样当我给它一个特定的日期时,它会为表中每个唯一的Item 返回一行,并且在给定日期它是Value或者如果它在给定日期未观察到,最后一次观察到

所以对于上表,如果我提供2018-12-01,它将返回:

| Item    | Date       | Value |
| A       | 2018-12-01 | 1     |
| B       | 2018-12-01 | 2     |
| C       | 2018-12-01 | 2     |

但如果我提供 2018-12-02 它会返回:

| Item    | Date       | Value |
| A       | 2018-12-02 | 3     |
| B       | 2018-12-02 | 3     |
| C       | 2018-12-01 | 2     |

【问题讨论】:

    标签: sql postgresql select


    【解决方案1】:

    你可以使用distinct on:

    select distinct on (item) t.*
    from t
    where date <= $your_date
    order by item, date desc;
    

    【讨论】:

    • 天哪。独特的功能是强大的。谈论混淆 SQL 虽然......
    • 不知道 distinct on。看起来很整洁的功能。是否仅在 postgres 中可用
    • @GeorgeJoseph 。 . .它特定于 Postgres(以及许多 Postgres 派生的数据库)。它比row_number() 等替代方案更强大、更高效。
    【解决方案2】:

    一种方法是查询该日期或之前的所有行,然后使用rank 窗口函数获取每个项目的第一个:

    SELECT item, date, value
    FROM   (SELECT item, date, value, RANK() OVER (PARTITION BY item ORDER BY date DESC) AS rk
            FROM   mytable
            WHERE  date <= :param_date) t
    WHERE  rk = 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-28
      • 2013-03-20
      • 2018-08-25
      • 2019-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-28
      相关资源
      最近更新 更多