【问题标题】:LINQ query help please. Selecting most recent record for each FK请帮助 LINQ 查询。为每个 FK 选择最近的记录
【发布时间】:2011-03-04 04:32:19
【问题描述】:

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

Id     CheckboxId     Selected     DateCreated
1      1              1            1/1/2010
2      2              1            1/2/2010
3      1              0            1/3/2010
4      3              1            1/4/2010
5      3              0            1/5/2010

CheckboxId 是一个 FK,该表只是复选框被选中或取消选中的历史记录。

我想要获取的是每个 CheckboxId 的最新记录。在我的演示表中,我需要第 2、3 和 5 行。你将如何做到这一点?此外,我确信这与查询开头的“位置”一样简单,但如果它也可以修改为仅获取指定日期之前的记录,那就太好了。

我无法弄清楚如何在 SQL 中编写查询来执行此操作,这使得链接查询变得不可能。我确信它必须是从不同的 checkboxIds 的子查询中选择的,再加上 group by 或其他东西,但我的 SQL 并不是那么好。

非常感谢您的帮助。

【问题讨论】:

    标签: sql linq


    【解决方案1】:

    应该是这样的:

    var results = (from x in context
           group x by x.CheckboxID into g
           select new
           {
               CheckboxID = g.Key,
               MaxItem = g.OrderByDescending(o => o.DateCreated).FirstOrDefault()
           });
    

    那么你可以这样做:

    foreach (var x in results)
        x.MaxItem.Selected //...etc.
    

    【讨论】:

    • 有趣。明天我会玩它,看看我能做什么。
    • 这基本上就是我最终要做的。我用其他 LINQ 语法编写它,因为我更喜欢它。所以我的最终查询最终是: var myItems = context.Source.Where(x => x.DateCreated x.CheckboxId).Select(grp => grp.OrderByDescending(x => x .DateCreated).FirstOrDefault()) 这也返回我的“源”项目而不是匿名数据类型,这对我来说似乎更好,我想不出什么理由。
    【解决方案2】:

    使用子查询获取每个 CheckBoxId 的最新条目,然后加入该表以获取其余结果:

    ;with CheckBoxRecent as (
        select
            CheckBoxId
           ,max(DateCreated) as MostRecentDate
        from
            CheckBoxData T
        where
            T.DateCreated < @SpecifiedDate
        group by
            CheckBoxId
    )
    select
        T1.*
    from
        CheckBoxData T1
    inner join
        CheckBoxRecent T2 on T1.CheckBoxId = T2.CheckBoxId
            and T1.DateCreated = T2.MostRecentDate
    order by
        CheckBoxId
    

    我将其作为练习留给读者转换为 LINQ :)

    【讨论】:

    • 这很好,但不是我所需要的。我需要实际的行,特别是我需要 Selected 列。我正在尝试回顾指定日期的历史记录,看看哪个 checkboxeId 的 Selected=1。
    • 丹丹!好的,我还没有设置我的表,但我相信这个查询现在是我在 SQL 中需要的。现在弄清楚如何在 LINQ 中做到这一点。
    • @William - 请看我的第一个答案,它应该让你非常接近你需要的东西。
    【解决方案3】:

    根据您的评论,您希望在指定日期选中复选框

    var results = db.CheckBoxHistory.Where(cbh => cbh.Selected == 1 && cbh.DateCreated.Date == DateSpecified)
    

    将为您提供这些结果,如果您想通过CheckboxId 将其限制为最新,只需添加此

    .GroupBy(cbh => cbh.CheckboxId)
    

    你可以像这样循环结果并为每个 checkboxid 获取最新的

    foreach(var result in results) {
        var latest = result.OrderByDescending(cbh => cbh.DateCreated).FirstOrDefault();
        //latest has all fields in the checkboxhistory table
    }
    

    【讨论】:

    • 我认为您不太了解我的需要。我需要每个复选框 ID 的最新历史记录。它不能只是最近的 selected=1 ,因为这会给我不准确的数据。例如,看看我 2010 年 1 月 5 日的表。我需要为复选框 3 获取记录 5,而不是为复选框 3 获取记录 4。使用您的第一个查询,我会错误地看到复选框 3 在 2010 年 1 月 5 日被选中。理解?您的第三个代码块将完成工作,但我希望有一种不那么蛮力的方法来做到这一点,即纯 LINQ 方式。
    • 然后只需删除 where 子句并按 checkboxid 分组,然后您可以根据需要为每个 checkboxid 订购集合并查看每个条目
    猜你喜欢
    • 2013-09-28
    • 2021-06-01
    • 2021-02-25
    • 2022-11-26
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多