【问题标题】:Group by query, each group has to not have any item not in a List按查询分组,每个组必须没有任何不在列表中的项目
【发布时间】:2016-11-25 02:50:44
【问题描述】:

需要一个可以帮助我解决这个问题的查询。

这是我的表“标签”:

  • id (int)
  • 名称(字符串)
  • user_id (int)
  • hardware_id (int)

我按hardware_id 对“tags”表的结果进行分组。我还有一个标签列表 (List<string>)。

我想在上表中的name 处获取自定义列表中所有标签匹配的组的硬件 ID。

换句话说,我想获取自定义列表标签与其name 匹配的hardware_id。自定义列表中可能有 name 没有匹配项,但所有自定义列表标签都必须在组中,如果满足此需求,我可以获取该组的 Id。

我发现很难解释,也没有得到答案。我考虑过用foreach来做,因为它很难解决,但我也做不到,这样做效率很低。

例子:

列表:['tag1', 'tag2']

表格行:

1, tag1, 5, 1
2, tag2, 5, 1
3, tag3, 5, 1
4, tag4, 5, 2
5, tag5, 6, 2

在这种情况下,我应该得到 1 的 hardware_id,因为虽然其中一个硬件 ID 有 tag3,但它没有任何标签名称不在列表中的行。如果 List 有 'tag4',则不会返回 hardware_id = 1,因为 List 有一个 hardware_id 组没有的标签。

如果 Group 没有 List 拥有的项目,则不会出现在最终结果中。

有人把这段代码给我玩了,但它没有用:

 List<decimal> matchingHardareIds = db.tags.GroupBy(x => x.hardware_id)
      .Where(x => x.All(s => tags.Contains(s.name.ToLower()) || 0 == tags.Count() && (s.user_id == userId)))
      .Select(x => x.Key).ToList();

在该查询中,当我在列表中有一个标签并且在表中我有几个 hardware_id 为 1 的项目并且其中一个的“名称”等于列表中的值时,它将返回空结果。这是因为按 hardware_id 划分的特定组的表中的行有一行的名称没有出现在自定义列表中。

我需要在 Entity Framework 或 Linq 中进行查询。非常感谢。

【问题讨论】:

    标签: sql entity-framework linq group-by entity-framework-4


    【解决方案1】:

    使用这个:

    var t = db.tags.GroupBy(x => x.hardware_Id)
              .Where(x => tags.All(y => 
                              x.Any(z=> z.name == y)))
              .Select(x=>x.Key).ToList();
    

    【讨论】:

    • 如果这行得通,我会给你我所有的stackoverflow积分
    • 对于您提供的示例,我确实对其进行了测试,并且有效。
    【解决方案2】:

    无法为您提供实体框架或linq查询,但sql解决方案是这样统计匹配:

    SELECT hardware_id 
    FROM tags
    WHERE name IN (<list>)
    GROUP BY hardware_id
    HAVING COUNT(DISTINCT name) = <listDistinctCount>
    

    &lt;listDistinctCount&gt; 是列表中不同值的计数。您可以在查询之前准备好。

    【讨论】:

    • 同一个hardware_id不能有重名
    • 那你就不需要 DISTINCT 部分了
    • 你会先阅读那些不匹配的人。剩下的那一次,必须有与 List 相同的行数。我到底要怎么把它翻译成 Linq.. LOL... 我需要一点时间。
    • 是的,这就是解决方案。如何翻译成 Linq - 帮不了你 :) 我看到你需要先创建组,然后使用 where(grp.Count = tags.Count())
    • 你有问题,不是吗? s =&gt; tags.Contains(s.name.ToLower())
    猜你喜欢
    • 1970-01-01
    • 2013-03-24
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多