获取“最近的”分组记录(按顺序排列)

Posted

技术标签:

【中文标题】获取“最近的”分组记录(按顺序排列)【英文标题】:Get 'most recent' grouped record (with order by) 【发布时间】:2021-11-04 05:18:20 【问题描述】:

我有如下查询

SELECT 
      t1.Supplier,
      t2.Product,
FROM 
      t1
INNER JOIN 
      t2 ON t1.ProductCode = t2.ProductCode
GROUP BY 
      t1.Supplier, t2.Product

在表 t1 上,还有名为“Timestamp”和“Price”的列 - 我想获取最新价格,即 SELECT Price ORDER BY Timestamp DESC。我可以使用任何聚合函数来执行此操作,还是必须是子查询?

【问题讨论】:

轻松为您提供帮助 - 向我们展示一些示例表数据和预期结果 - 全部为格式化文本(不是图像)。minimal reproducible example 这能回答你的问题吗? Get the latest records per Group By SQL 您是否需要查询中显示的基于您的组的结果? @克里斯 【参考方案1】:

执行此操作的一种标准方法是使用ROW_NUMBER() 在源数据中创建一个附加列,以便您识别每个“分区”中的“第一行”。

WITH
  supplier_sorted AS
(
  SELECT
    *,
    ROW_NUMBER() OVER (PARTITION BY supplier, ProductCode
                           ORDER BY timestamp DESC
                      )
                        AS recency_id
  FROM
   supplier
)
SELECT
  s.Supplier,
  p.Product,
  COUNT(*)
FROM
  supplier_sorted  AS s
INNER JOIN
  product          AS p
    ON s.ProductCode = p.ProductCode
WHERE
  s.recency_id = 1
GROUP BY
  s.Supplier,
  p.Product

【讨论】:

你为什么在这里使用 Count(*) ? @Gudwlk - 作为使用聚合的示例。 OP 使用 GROUP BY 而不是 DISTINCT and, 结束 SELECT 子句,暗示他们打算在那里放“东西”。【参考方案2】:

你可以使用cross apply:

SELECT t2.*, t1.*
FROM t2 CROSS APPLY
     (SELECT TOP (1) t1.*
      FROM t1
      WHERE t1.ProductCode = t2.ProductCode
      ORDER BY t1.TimeStamp DESC
     ) t1;

所以,GROUP BY 是不必要的。

【讨论】:

【参考方案3】:

可以在 ProductCode 和 Supplier 的分区上使用 row_number() 来通过 desc 使用 Timestamp Order 来获取基于分区的最新记录。然后,您可以在不聚合的情况下在同一个查询中使用以获得所需的结果。 对于这些问题,最好使用 Windows 函数而不是 Group by。

SELECT 
   A.Supplier
  ,A.Product
  ,A.Price
FROM
  (
  SELECT 
     t1.Supplier,
     t2.Product,
     T1.Price,
     ROW_NUMBER () OVER ( PARTITION BY t1.Supplier,t2.Product ORDER BY  T1.[Timestamp] DESC ) AS  row_num    
   FROM   t1
    INNER JOIN t2 
      ON t1.ProductCode = t2.ProductCode
    ) AS A WHERE A.row_num = 1 

使用以下添加的数据进行测试。

 CREATE TABLE t1
  ( Supplier varchar(100)
   ,ProductCode int 
   , Price Decimal (10,2)
   , [TimeStamp] datetime
  )

CREATE TABLE t2
( 
 ProductCode int 
 ,Product varchar(100)
 )

  insert into t1 values ('A', 1, 100.00, GetDate())
  insert into t1 values ('A', 1, 80.00, GetDate())
  insert into t1 values ('b', 2, 190.00, GetDate())
  insert into t1 values ('b', 2, 500.00, GetDate())

  insert into t2 values (1, 'Pro1')
  insert into t2 values (2, 'Pro2')
  insert into t2 values (3, 'Pro3')

【讨论】:

以上是关于获取“最近的”分组记录(按顺序排列)的主要内容,如果未能解决你的问题,请参考以下文章

获取每组分组结果的前 n 条记录

获取每组分组结果的前 n 条记录

MySQL按X排序然后分组按Y然后按字母顺序排列

UITableview 的名称部分按排序顺序排列

《淘宝》购物车按店铺顺序排列教程

mysql根据汉字首字母排序的方法并按字母分组