如何在LINQ或SQL中获取每个“类型”的最后一个元素

时间:2010-05-13 10:39:00

标签: linq linq-to-sql tsql

想象一下将表定义为

CREATE TABLE [dbo].[Price](
    [ID] [int] NOT NULL,
    [StartDate] [datetime] NOT NULL,
    [Price] [int] NOT NULL
)

其中ID是具有特定价格的动作的标识符。如有必要,可以通过添加具有相同ID,不同价格和更新日期的新行来更新此价格。

所以使用一组数据,如

ID StartDate价格

1  01/01/2009 10
1  01/01/2010 20
2  01/01/2009 10
2  01/01/2010 20

如何获得如下的集合?

1  01/01/2010 20
2  01/01/2010 20

3 个答案:

答案 0 :(得分:2)

在SQL中,有几种方式可以说。这是使用子查询的那个:

SELECT *
  FROM Price p
 WHERE NOT EXISTS (
        SELECT *
          FROM Price
         WHERE ID = p.ID
           AND StartDate > p.StartDate
       )

这很简单地转换为LINQ:

var q = from p in ctx.Price
        where !(from pp in ctx.Price
                where pp.ID == p.ID
                   && pp.StartDate > p.StartDate
                select pp
               ).Any()
        select p;

或者我应该说,我认为确实如此。我现在不在VS前面,所以我无法验证这是否正确,或LINQ是否能够将其转换为SQL。

轻微狡辩:不要使用名称ID来存储非唯一值(在本例中为类型)。这令人困惑。

答案 1 :(得分:1)

假设ID& StartDate将是唯一的:

SELECT p.ID, p.StartDate, p.Price
FROM Price p
    JOIN 
    (
        SELECT ID, MAX(StartDate) AS LatestDate
        FROM Price
        GROUP BY ID
    ) p2 ON p.ID = p2.ID AND p.StartDate = p2.LatestDate

答案 2 :(得分:1)

由于您使用LINQ to SQL标记了问题,因此这是一个LINQ查询来表达您想要的内容:

from price in db.Prices
group price by price.Id into group
let maxDateInGroup = group.Max(g => g.StartDate)
let maxDatePrice = group.First(g => g.StartDate == maxDateInGroup)
select
{
    Id = group.Key,
    StartDate = maxDatePrice.StartDate,
    Price = maxDatePrice.Price
};