【问题标题】:Linq To Sql / SQL Query HelpLinq To Sql / SQL 查询帮助
【发布时间】:2010-08-26 20:11:00
【问题描述】:

我有一张如下所示的表格:

Id    PageId    Key    Content    LastUpdated
---------------------------------------------

 1     12       key1    content1   02-21-2010
 2     12       key1    content2   02-25-2010
 3     12       key2    content1   02-21-2010
 4     12       key2    content2   02-25-2010
 5     12       key3    content1   02-21-2010

我需要做的是查询由 LastUpdated 排序的 PageId 的不同列表,因此我的结果如下所示:

2     12       key1    content2
4     12       key2    content2
5     12       key3    content1

我正在使用 Linq-2-Sql,但如果需要,我可以使用 SP。任何有关如何完成此操作的帮助都会很棒,谢谢!

【问题讨论】:

  • 基于 PageId 的不同列表只会返回 1 行,而不是 3 行。看起来您想要一个不同的“键”,但只返回具有最新 LastUpdated 的行。这是正确的吗?

标签: sql-server linq-to-sql


【解决方案1】:

这是一个仅使用 tsql 的想法,您可以将其放入 SP。 (假设 LastUpdated 是一个日期时间字段,而不是您列出的格式的字符串,并假设至少 SQL 2005 使用CTE。如果这些假设不正确,则可以克服这些假设。):

;with cteMaxUpdated as (
    select Key, max(LastUpdated) as MaxUpdated
        from YourTable
        group by Key
)
select yt.Id, yt.PageId, yt.Key, yt.Content
    from cteMaxUpdated mu
        inner join YourTable yt
            on mu.Key = yt.Key
                and mu.MaxUpdated = yt.LastUpdated

【讨论】:

  • 您的解决方案与 Frank 的解决方案有性能差异吗?
  • 我不这么认为,但不能 100% 确定。尝试每个并比较执行计划、IO 统计数据等。
  • 我只记得在another question 中使用 MAX 的性能优于 ROWNUMBER。再次针对您的具体情况进行测试。
【解决方案2】:

在 SQL 中,这将按如下方式工作:

WITH i as (
  SELECT Id, PageId, Key, Content, dense_rank() over(PARTITION BY Key ORDER BY LastUpdated desc) as pos
    FROM myTable
)
SELECT Id, PageId, Key, Content
  FROM i
 WHERE pos = 1

我在这里假设您的意思是“按键不同的列表”而不是“PageId 的不同列表”。

您应该知道,如果每个键的日期不是唯一的,这将返回键的最大日期的所有记录。如果您只想拥有其中一个,您可以在 ORDER BY 中添加其他字段。

如果您不关心每个键返回几个非唯一记录中的哪一个,则可以使用 ROW_NUMBER() 而不是 DENSE_RANK()。

【讨论】:

  • 这很好用。您的解决方案与 Joe 的解决方案之间是否存在性能差异?
  • @Paul 我假设没有连接。但这取决于许多因素,因此最好测试您的具体情况。