【问题标题】:mySQL - Selecting the latest row from a tablemySQL - 从表中选择最新的行
【发布时间】:2020-07-19 04:28:23
【问题描述】:

我正在使用 mySQL v5.7.29 MySQL 社区服务器 (GPL)

我有一个表,我在其中创建了一个唯一索引以避免在以下列(除时间戳Updated 之外的所有列)上插入重复值:

CREATE UNIQUE INDEX daily_unique ON daily(`Contract Date`, `Delivery`, `Product`, `Region`, `Price`)

我需要通过更新(时间戳)选择最新的记录。

我尝试了以下方法:

SELECT * FROM daily
WHERE updated = ( SELECT max(Updated) FROM daily ) 

但是,因为有多个Delivery、Product、Region,上面的不行。

以下是记录的摘录:

     Contract Date    Delivery      Product Region   Price   Updated
0    2020-04-06       2020-04-01    A       B        1       2020-04-06 23:00:17
1    2020-04-06       2020-04-01    A       B        2       2020-04-07 10:30:16

我需要查询只返回最新的记录(每组交货、产品和地区应该只返回一个合同日期和价格)。

     Contract Date    Delivery      Product Region   Price   Updated
1    2020-04-06       2020-04-01    A       B        2       2020-04-07 10:30:16

【问题讨论】:

  • 什么是dialy:一个表,一个属性?我看到了: WHERE daily = ... 但没有一个名为 like 的属性
  • 我很抱歉 - 更新的是我希望选择 max on 的属性,每天是表名

标签: mysql sql


【解决方案1】:

如果您使用的是 MySQL 8+,那么ROW_NUMBER 是这里的方法:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Delivery, Product, Region
                                 ORDER BY Updated DESC) rn
    FROM daily
)

SELECT `Contract Date`, Delivery, Product, Region, Price, Updated
FROM cte
WHERE rn = 1;

对于每组交货/产品/地区记录,上面的行号将从最近更新的记录开始,从 1 开始。然后,我们查询 CTE 以仅保留每个组的最新记录。

以防万一您使用的是早期版本的 MySQL,这里有另一种方法:

SELECT d1.`Contract Date`, d1.Delivery, d1.Product, d1.Region, d1.Price, d1.Updated
FROM daily d1
INNER JOIN
(
    SELECT Delivery, Product, Region, MAX(Updated) AS MaxUpdated
    FROM daily
    GROUP BY Delivery, Product, Region
) d2
    ON d1.Delivery = d2.Delivery AND
       d1.Product  = d2.Product AND
       d1.Region   = d2.Region AND
       d1.Updated  = d2.MaxUpdated;

【讨论】:

  • 感谢您的回复,不幸的是,mySQL v5 不允许使用 CTE 表达式...也许我可以使用视图来代替 CTE?
  • 似乎 mySQL v5 也没有 ROW_NUMBER() 的本机函数..
  • 感谢您为我节省了打字... :)
  • 我还给了你一个查询,它应该适用于早期版本的 MySQL。
  • @Nick 我希望大家尽快升级...厌倦了写那个旧查询:-)
【解决方案2】:

您也可以使用 correlated 子查询:

SELECT d.*
FROM daily d
WHERE d.updated = (SELECT MAX(d1.updated)
                   FROM daily d1 
                   WHERE d.Delivery = d1.Delivery AND
                         d.Product  = d1.Product AND
                         d.Region   = d1.Region AND
                  );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 2022-12-03
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    相关资源
    最近更新 更多