【问题标题】:SQL Query: Display only latest Id from each setSQL 查询:仅显示每组的最新 ID
【发布时间】:2018-06-14 15:22:12
【问题描述】:

我有以下 SQL 表:

Name       Description   Id   UserId   CreatedDate
UserSet1   Desc1         1    Abc      06/01/2018
UserSet1   Desc2         2    Def      06/02/2018
UserSet2   Desc for 2    5    NewUser  06/04/2018
UserSet2   Desc for 2    7    NewUser  06/19/2018

我想从上表中提取的只是每个 Name 的最新 Id,以便我可以得到以下输出

Name      Description    Id    UserId    CreatedDate
UserSet1  Desc2          2     Def       06/01/2018
UserSet2  Desc for 2     7     NewUser   06/19/2018

由于 Id 2 和 7 是表中 UserSet1 和 UserSet2 的最新条目,我想显示它而不是表中的所有条目。

我怎样才能得到想要的结果。

我对直接返回输出的解决方案或任何 linq (C#) 解决方案持开放态度。即返回整个数据集,然后使用 linq 过滤上述内容。

【问题讨论】:

  • 可以使用窗口函数。
  • 如果你可以访问 SQL,你可以 GROUP BY Name 和 SELECT TOP 1 Id
  • SQL 的版本和风格是什么?
  • 我实际上使用的是 AWS 的 Dynamo DB。抱歉,这是我第一次使用 dynamo db。既然我认为它是一个无 sql 数据库,那么只有在我们从数据库中获取全部结果后才能过滤掉代码中的结果。
  • DynamoDB 是否允许您使用SELECT 未包含在GROUP BY 中的列?

标签: c# sql linq amazon-dynamodb


【解决方案1】:

编辑:由于您正在寻找最高编号的 ID,GROUP BY 方法可能更容易使用。

使用窗口函数:

SELECT *
FROM (
    SELECT Name, Description, Id, UserId, CreatedDate
        , ROW_NUMBER() OVER (PARTITION BY Name ORDER BY CreatedDate DESC) AS rn
    FROM myTable
) s1
WHERE rn = 1

我没有要测试的 dynamoDB 实例,但我相信它可以使用 ROW_NUMBER() 窗口函数。

【讨论】:

  • 您可能还想在您的数据库中创建一个view,然后只查询该view。这样您就不会尝试在 Linq 中构建所需的结果。
【解决方案2】:

感谢大家指出正确的方向。我已经使用下面的 Linq 和 C# 代码来实现这一点:

 var results = response.GroupBy(row => row.Name)
                   .SelectMany(g => g.OrderByDescending(row => row.Id).Take(1));

对于最初的测试,这似乎是有效的。如果您认为这有问题,请告诉我。

【讨论】:

  • 这里只有一件事是我想为此添加另一个条件。除了上面获得的结果集外,我还希望结果显示所有 ID 为 0 的 ID。所以我的结果集将包含 ID 2、7 和 0。如何修改上述 Linq 的任何输入?
【解决方案3】:

这应该是一个通用的 SQL 答案:

SELECT * FROM yourtable Y1
WHERE Id = (SELECT MAX(Id)
              FROM yourtable Y2
             WHERE Y2.Name = Y1.Name)

【讨论】:

    【解决方案4】:

    如果是 MS SQL,你可以使用 Partition By 命令,否则最高效的方式是:

    select * from Table
    where Id in (
        select Max(Id) from Table
        Group By Name
    )
    

    不确定是否可以将 Name 排除在 Select 语句之外,您可能需要这样做:

    select * from Table
    where Id in (
        Select Id from 
            (select Name, Max(Id) as Id from Table
            Group By Name)
    )
    

    【讨论】:

    • RE:MS SQL 性能 >> 我认为优化器对于 IN 子句与 PARTITION BY 子句的性能不会更好。 IN (1,2,3,...) 本质上是 WHERE Id = 1 or Id = 2 OR Id = 3 OR ... 的缩写。对于大型子查询,它可能是一个非常复杂的语句。 PARTITION BY 仍然是基于集合的。
    • @user007,你知道如何用 LINQ for C# 编写相同的代码
    • @Shawn 关于性能,我正在考虑相关子查询,因为我可以看到有些人有他们的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多