1

我有一个简单的查询:选择 parentId 不为空的最新行。我已经在 LINQ(lambda) 和 SQL 中制定了查询。我正在尝试检索最近的孩子。我将尝试可视化我需要的数据。

原始数据:

-------------------------------
- Id - ParentId - CreatedDate -
-------------------------------
-  1 -          -  07/01/2013 -
-  2 -          -  07/01/2013 -
-  3 -          -  07/01/2013 -
-  4 -        1 -  07/02/2013 -
-  5 -        2 -  07/03/2013 -
-  6 -        2 -  07/04/2013 -
-  7 -        1 -  07/05/2013 -
-------------------------------

查询返回的数据

-------------------------------
- Id - ParentId - CreatedDate -
-------------------------------
-  6 -        2 -  07/04/2013 -
-  7 -        1 -  07/05/2013 -
-------------------------------

这是我目前正在尝试的:

SQL:

SELECT a."ParentId", MAX(a."CreatedDate")
FROM "myTable" AS a
WHERE a."ParentId" IS NOT NULL
GROUP BY a."ParentId"

LINQ(λ):

var uniqueChildren = myTable.Where(a => a.ParentId != null)
        .GroupBy(a => a.ParentId)
        .Select(b => new { ParentId = b.Key, CreatedDate = b.Max(t => t.CreatedDate) });

这将返回几行,其中包括键 (ParentId) 和创建日期。我希望它返回整行而不是两条信息。我搜索了类似的问题并找到了可能的解决方案:

var q = from n in table
        group n by n.ParentId into g
        select g.OrderByDescending(t=>t.CreatedDate).First();

这看起来很有希望,所以我对我的 PostgreSQL 数据库运行它并从 VisualStudio 收到以下错误:

"The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead."

好的,该消息非常简单,让我试试这样:

var q = from n in table
        group n by n.ParentId into g
        select g.OrderByDescending(t=>t.CreatedDate).FirstOrDefault();

现在我得到另一个错误:

The method or operation is not implemented

我似乎无法在这里休息一下。我继续使用我知道不会引起任何问题的命令拼凑出一个看起来很草率的解决方案:

var q2 =
    (from a in myTable
     join b in
         (myTable.Where(a => a.ParentId != null)
                 .GroupBy(a => a.ParentId)
                 .Select(b => new { 
                                     ParentId = b.Key, 
                                     CreatedDate = b.Max(t => t.CreatedDate) 
                                  }))
     on a.ParentId equals b.ParentId
     where a.CreatedDate == b.CreatedDate
     select a);

这样就可以检索到我需要的东西,但我怀疑有一种更优雅的方式来完成这项任务。有哪些替代方法可以做到这一点?任何帮助是极大的赞赏。

4

1 回答 1

1

我可能会做这样的事情:

对所有记录进行排序,以使最新的记录排在第一位,然后取最前面的记录。

var q = (from a in myTable
         where a.ParentId != null
         orderby a.CreatedDate descending
         select a).Take(1).ToList();

应该生成如下所示的 SQL:

SELECT TOP 1 *
FROM MyTable a
WHERE a.CreatedDate IS NOT NULL
ORDER BY a.CreatedDate DESC

更新

啊,所以你想要每组相关孩子的最新孩子。然后像这样的东西应该可以解决问题。我想该Take方法将适用于您的提供商。好像FirstOrDefault还没有实现,因为你已经尝试过了。

var q =
    from t in myTable
    where t.ParentId != null
    group t by t.ParentId into grp
    select grp.OrderByDescending(p => p.CreatedDate).Take(1);
于 2013-07-03T19:44:52.763 回答