LINQ 与 GROUP BY 和 HAVING COUNT
LINQ with GROUP BY and HAVING COUNT
我想了解我在 Linq 中的 GROUP BY
查询做错了什么。我已经尝试了很多示例(即 Linq with group by having count),但我仍然得到了更多结果(因为 WHERE
被跳过了)。我的代码是这样的:
var test = session.Query<SomeClass>()
.GroupBy(c => new { c.Var1, c.Var2, c.Var3 })
.Where(g => g.Count() > 1)
.Select(g => g.Key.Var3)
.ToList();
这给出了 229 个结果(所有记录)。我想在 Linq 中构建的查询是:
SELECT Var3
FROM myTable
GROUP BY Var1, Var2, Var3
HAVING COUNT(*) > 1
不知何故,查询给了我 27 个结果,但 Linq 表达式给了我 229(全部)。当我将 Linq 表达式的 where/select 部分替换为以下内容时,我确实得到了一个计数为 2 或更高的列表:
.Select(g => new { Item = g.Key, Count = g.Count() })
但我不想要一个包含项目(和计数)的列表并且不必遍历该列表,我想让 HAVING
部分在 Linq 表达式中工作...
编辑 2:如果您看一下 LINQ Group By Multiple fields -Syntax help,这对我也适用。但是,我将获得包含 Var1、Var2、Var3 和 Count 的对象列表。在这个列表中,我只想要 Count 大于 1 的对象的 Var3。
谁能给我指出正确的方向?
编辑 1:正如我在介绍中所说,问题 Linq with group by having count 没有回答我的问题。如果我使用此代码,我仍然有一组 229 个结果,而不是实际上 "duplicated" 的 27 个结果(意思是,在该组的计数超过 1 之后)。
编辑 3:我现在正在使用以下内容。我需要两个语句,我认为这很奇怪,但如前所述,这似乎是 select 只有计数 > 1 的记录的唯一方法。
var querygroup = session.Query<SomeClass>()
.GroupBy(e => new { e.Var1, e.Var2, e.Var3 })
.Select(s => new { s.Key.Var1, s.Key.Var2, s.Key.Var3, Count = s.Count() })
.ToList();
var duplicates = querygroup.Where(g => g.Count > 1)
.Select(g => new SomeClass() { Var1 = g.Var1, Var2 = g.Var2, Var3 = g.Var3})
.ToList();
请注意,我决定 select 也 select 值 Var1 和 Var2 并将它们存储在 SomeClass() 中,而不是仅 select ing Var3。这只是一个补充,selecting 一切都无助于创建 1 个语句来获得这个 selection。
编辑 4:我当然可以将 duplicates
变量中的 .Where..
部分添加到 querygroup
语句中,从而形成整个语句。成功?看起来有点矫枉过正,但至少它有效。
如果有人能找出为什么我需要 2 个语句,请详细说明:)
您可以在 Linqpad 试试这个。我更改了查询的 table 和列名以匹配我自己的数据库:
Levels
.GroupBy(c => new { c.CourseGuid, c.ModuleName })
.Where(g => g.Count() > 10)
.Select(g => g.Key.CourseGuid)
这是它生成的 SQL 查询:
-- Region Parameters
DECLARE @p0 Int = 10
-- EndRegion
SELECT [t1].[CourseGuid]
FROM (
SELECT COUNT(*) AS [value], [t0].[CourseGuid]
FROM [xrt].[Levels] AS [t0]
GROUP BY [t0].[CourseGuid], [t0].[ModuleName]
) AS [t1]
WHERE [t1].[value] > @p0
不是 HAVING COUNT,而是 WHERE,功能相同。使用 @p0 参数显示输出已正确过滤。
我建议您尝试使用 Linqpad,看看您的查询对您的数据做了什么。
试试这个
var test = session.Query<SomeClass>()
.GroupBy(c => new { c.Var1, c.Var2, c.Var3 })
.Select(d=> new { var1 = d.Key.var1,var2 = d.Key.var2,var3=d.Key.var3,records = d.ToList()})
.Where(e => e.records.Count() > 1)
.Select(g => g.Var3)
.ToList();
所以,我的问题的答案:
var duplicates = session.Query<SomeClass>()
.GroupBy(e => new { e.Var1, e.Var2, e.Var3 })
.Select(s => new { s.Key.Var1, s.Key.Var2, s.Key.Var3, Count = s.Count() })
.ToList()
.Where(g => g.Count > 1)
.Select(g => new SomeClass() { Var1 = g.Var1, Var2 = g.Var2, Var3 = g.Var3})
.ToList();
好像有点矫枉过正,我觉得它可以更小,所以如果有人愿意对此发表评论...
我想了解我在 Linq 中的 GROUP BY
查询做错了什么。我已经尝试了很多示例(即 Linq with group by having count),但我仍然得到了更多结果(因为 WHERE
被跳过了)。我的代码是这样的:
var test = session.Query<SomeClass>()
.GroupBy(c => new { c.Var1, c.Var2, c.Var3 })
.Where(g => g.Count() > 1)
.Select(g => g.Key.Var3)
.ToList();
这给出了 229 个结果(所有记录)。我想在 Linq 中构建的查询是:
SELECT Var3
FROM myTable
GROUP BY Var1, Var2, Var3
HAVING COUNT(*) > 1
不知何故,查询给了我 27 个结果,但 Linq 表达式给了我 229(全部)。当我将 Linq 表达式的 where/select 部分替换为以下内容时,我确实得到了一个计数为 2 或更高的列表:
.Select(g => new { Item = g.Key, Count = g.Count() })
但我不想要一个包含项目(和计数)的列表并且不必遍历该列表,我想让 HAVING
部分在 Linq 表达式中工作...
编辑 2:如果您看一下 LINQ Group By Multiple fields -Syntax help,这对我也适用。但是,我将获得包含 Var1、Var2、Var3 和 Count 的对象列表。在这个列表中,我只想要 Count 大于 1 的对象的 Var3。
谁能给我指出正确的方向?
编辑 1:正如我在介绍中所说,问题 Linq with group by having count 没有回答我的问题。如果我使用此代码,我仍然有一组 229 个结果,而不是实际上 "duplicated" 的 27 个结果(意思是,在该组的计数超过 1 之后)。
编辑 3:我现在正在使用以下内容。我需要两个语句,我认为这很奇怪,但如前所述,这似乎是 select 只有计数 > 1 的记录的唯一方法。
var querygroup = session.Query<SomeClass>()
.GroupBy(e => new { e.Var1, e.Var2, e.Var3 })
.Select(s => new { s.Key.Var1, s.Key.Var2, s.Key.Var3, Count = s.Count() })
.ToList();
var duplicates = querygroup.Where(g => g.Count > 1)
.Select(g => new SomeClass() { Var1 = g.Var1, Var2 = g.Var2, Var3 = g.Var3})
.ToList();
请注意,我决定 select 也 select 值 Var1 和 Var2 并将它们存储在 SomeClass() 中,而不是仅 select ing Var3。这只是一个补充,selecting 一切都无助于创建 1 个语句来获得这个 selection。
编辑 4:我当然可以将 duplicates
变量中的 .Where..
部分添加到 querygroup
语句中,从而形成整个语句。成功?看起来有点矫枉过正,但至少它有效。
如果有人能找出为什么我需要 2 个语句,请详细说明:)
您可以在 Linqpad 试试这个。我更改了查询的 table 和列名以匹配我自己的数据库:
Levels
.GroupBy(c => new { c.CourseGuid, c.ModuleName })
.Where(g => g.Count() > 10)
.Select(g => g.Key.CourseGuid)
这是它生成的 SQL 查询:
-- Region Parameters
DECLARE @p0 Int = 10
-- EndRegion
SELECT [t1].[CourseGuid]
FROM (
SELECT COUNT(*) AS [value], [t0].[CourseGuid]
FROM [xrt].[Levels] AS [t0]
GROUP BY [t0].[CourseGuid], [t0].[ModuleName]
) AS [t1]
WHERE [t1].[value] > @p0
不是 HAVING COUNT,而是 WHERE,功能相同。使用 @p0 参数显示输出已正确过滤。
我建议您尝试使用 Linqpad,看看您的查询对您的数据做了什么。
试试这个
var test = session.Query<SomeClass>()
.GroupBy(c => new { c.Var1, c.Var2, c.Var3 })
.Select(d=> new { var1 = d.Key.var1,var2 = d.Key.var2,var3=d.Key.var3,records = d.ToList()})
.Where(e => e.records.Count() > 1)
.Select(g => g.Var3)
.ToList();
所以,我的问题的答案:
var duplicates = session.Query<SomeClass>()
.GroupBy(e => new { e.Var1, e.Var2, e.Var3 })
.Select(s => new { s.Key.Var1, s.Key.Var2, s.Key.Var3, Count = s.Count() })
.ToList()
.Where(g => g.Count > 1)
.Select(g => new SomeClass() { Var1 = g.Var1, Var2 = g.Var2, Var3 = g.Var3})
.ToList();
好像有点矫枉过正,我觉得它可以更小,所以如果有人愿意对此发表评论...