我需要一些帮助创建一个LINQ选择,我有一个表中包含一些列,但只有2个问题的兴趣。
userid, type
现在这个表有几千个条目,我只想要顶部,让我们说50.到目前为止一直很好,但很难的是有很多行成功,只能算作1。 实施例
Type UserId
============
Add 1
Add 1
Add 1
Add 2
我希望这只能在我取出的行数限制中计为2,但我希望所有行都能输出。 这可能是单个SQL请求,还是我应该找到另一种方法来执行此操作?
编辑:我可以在表中添加列,如果这样可以解决问题。 Edit2:Sotred程序也是一个解决方案
示例2:这应该算作3行
Type UserId
============
Add 1
Add 1
Add 2
Add 1
答案 0 :(得分:1)
我现在不接近电脑,所以我不确定语法是否正确100%,但我相信你正在寻找这样的东西:
data.Select(x => new {x.Type, x.UserId})
.GroupBy(x => x.UserId)
.Take(50);
答案 1 :(得分:1)
你可以使用Linq来做,但它可能比传统的for
循环慢很多。一种方法是:
data.Where((s, i) => i == 0 ||
!(s.Type == data[i-1].Type && s.UserId == data[i-1].UserId))
这会跳过任何与“上一个”项目具有相同Type和UserID的“重复”项目。
但是,如果data
有一个索引器(一个数组或一个实现IList
的东西),这只能起作用。 IEnumerable
或IQueryable
不起作用。此外,它几乎肯定不能转换为SQL,因此您必须提取所有结果并过滤内存。
如果您想在SQL中执行此操作,我会尝试扫描游标并填充临时表(如果其中一个值更改或使用包含ROW_NUMBER
列的公用表表达式,然后查看 - 返回子查询类似于上面的Linq方法:
WITH base AS
(
SELECT
Type,
UserId,
ROW_NUMBER() OVER (ORDER BY ??? ) AS RowNum
FROM Table
)
SELECT b1.Type, b1.UserId
FROM base b1
LEFT JOIN base b2 ON b1.RowNum = b2.RowNum - 1
WHERE (b1.Type <> b2.Type OR b1.UserId <> b2.UserId)
ORDER BY b1.RowNum
答案 2 :(得分:1)
您可以使用LINQ执行此操作,但我认为可能更容易使用“for(each)loop”路径......
data.Select((x, i) => new { x.Type, x.UserId, i })
.GroupBy(x => x.Type)
.Select(g => new
{
Type = g.Key,
Items = g
.Select((x, j) => new { x.UserId, i = x.i - j })
})
.SelectMany(g => g.Select(x => new { g.Type, x.UserId, x.i }))
.GroupBy(x => new { x.Type, x.i })
.Take(50);
.SelectMany(g => g.Select(x => new { x.Type, x.UserId }));
答案 3 :(得分:1)
你坚持使用LINQ吗?
添加PK身份 按PK命令 使用DataReader只计算更改 然后在更改计数达到最大值时停止。
如果您不在.NET环境中,那么使用游标也是如此。
由于LINQ被推迟,你可能只能在LINQ中订购,然后在ForEach上退出。