SQL - 使用分组方式选择,从具有最大值(日期)的寄存器中获取数据

Posted

技术标签:

【中文标题】SQL - 使用分组方式选择,从具有最大值(日期)的寄存器中获取数据【英文标题】:SQL - Select with group by, Get data from the register with the max(date) 【发布时间】:2020-08-07 07:03:44 【问题描述】:

我在数据库中有两个表:ProductProductVersion,每个产品可以有n个ProductVersions。 ProductVersion 有这个字段(Id、name、origin、date、provider)

我想要一个查询,我在其中获取产品信息,并在同一个注册中使用最大日期的 productversion 信息,如下所示:

select
p.ProductId, p.ProductName , max(pv.date), name of  max(pv.date), origin of  max(pv.date)
from Product p Join ProductVersion pv on p.ProductId = pv.ProductId
where userId = 'test_user'
group by p.Id

我想创建一个从 c# 调用的视图,我正在使用 linq,但这种情况下的性能并不好,所以我正在尝试使用我需要的信息的视图。我想用 SQL 查询来实现这样的事情。

var result =
_context.ProductVersion
    .Where(x => x.UserId == userId)
    .GroupBy(x => x.ProductId)
    .Select(group => group.OrderByDescending(x => x.Date).FirstOrDefault())
    .Include(x => x.Product)
    .ToList();

【问题讨论】:

【参考方案1】:

应该这样做。

DECLARE @userID NVARCHAR(100) = N'test_user'

WITH cte
AS
(
    SELECT
        p.ProductID
        ,p.ProductName
        ,pv.Date as VersionDate
        ,pv.Name as VersionName
        ,pv.Origin as VersionOrigin
        ,ROW_NUMBER() OVER (PARTITION BY p.ProductID ORDER BY pv.Date DESC) as PartitionID
    FROM product p
        inner join ProductVersion  pv on p.ProductId = pv.ProductID
    WHERE userID = @userID
)

SELECT 
    ProductID
    ,ProductName
    ,VersionDate
    ,VersionName
    ,VersionOrigin
FROM cte
WHERE PartitionID = 1

【讨论】:

我通过一些更改来实施这种方法,这对我们来说是最好的解决方案,谢谢。【参考方案2】:

我了解到您希望 ProductVersion 为每个 Product 提供最新行。 SQL Server 中一种简单有效的方法是横向连接:

create view myview as
select p.*, pv.name, pv.origin, pv.date, pv.provider
from product p
cross apply (
    select top (1) *
    from productVersion pv
    where p.productId = pv.productId
    order by pv.date desc
)

【讨论】:

我正在尝试这种方法,目前我在某些连接方面遇到了一些问题

以上是关于SQL - 使用分组方式选择,从具有最大值(日期)的寄存器中获取数据的主要内容,如果未能解决你的问题,请参考以下文章

SQL:选择具有最大值的行并按单列分组

MDX 查询以对具有特定日期范围的日期维度进行分组

Oracle SQL 选择具有开始和结束日期的行,如果某些重叠合并行

SQL选择具有最大和最小日期的行

SQL Server:从最大日期/最新日期的记录中获取数据

从表中选择具有最大日期的行