我有一个包含行的数据库表,每行包含一个顺序索引。我想根据此索引列选择连续的行组。例如,如果我的行包含以下索引值:
1
3
4
5
7
9
10
11
12
15
16
我希望选择所有具有3个连续索引的组(此数字会有所不同)。我会得到以下几组:
3, 4, 5
9, 10, 11
10, 11, 12
基本上,我正在努力实现类似于此处提出的问题:
selecting consecutive numbers using SQL query
但是,我想用LINQ to Entities实现它,而不是实际的SQL。我也不想使用存储过程,我不想做任何类型的ToList /循环方法。
编辑:具有多个请求的连续元素的组不一定需要拆分。即在前面的例子中,9,10,11,12的结果也是可以接受的。
答案 0 :(得分:1)
所以我认为我已经提出了一个非常好的解决方案,模仿Brian在我链接的主题中的回答。
var q = from a in query
from b in query
where a.Index < b.Index
&& b.Index < a.Index + 3
group b by new { a.Index }
into myGroup
where myGroup.Count() + 1 == 3
select myGroup.Key.Index;
将3更改为所需的连续行数。这为您提供了每组连续行的第一个索引。应用于我提供的原始示例,您将获得:
3
9
10
答案 1 :(得分:1)
我认为这可能非常有效(C#):
int[] query = { 1, 3, 4, 5, 7, 9, 10, 11, 12, 15, 16 };
int count = 3;
List<List<int>> numbers = query
.Where(p => query.Where(q => q >= p && q < p + count).Count() == count)
.Select(p => Enumerable.Range(p, count).ToList())
.ToList();
答案 2 :(得分:0)
using (var model = new AlbinTestEntities())
{
var triples = from t1 in model.Numbers
from t2 in model.Numbers
from t3 in model.Numbers
where t1.Number + 1 == t2.Number
where t2.Number + 1 == t3.Number
select new
{
t1 = t1.Number,
t2 = t2.Number,
t3 = t3.Number,
};
foreach (var res in triples)
{
Console.WriteLine(res.t1 + ", " + res.t2 + ", " + res.t3);
}
}
它生成以下SQL
SELECT
[Extent1].[Number] AS [Number],
[Extent2].[Number] AS [Number1],
[Extent3].[Number] AS [Number2]
FROM [dbo].[Numbers] AS [Extent1]
CROSS JOIN [dbo].[Numbers] AS [Extent2]
CROSS JOIN [dbo].[Numbers] AS [Extent3]
WHERE (([Extent1].[Number] + 1) = [Extent2].[Number]) AND (([Extent2].[Number] + 1) = [Extent3].[Number])
使用像这样的内连接可能更好
using (var model = new AlbinTestEntities())
{
var triples = from t1 in model.Numbers
join t2 in model.Numbers on t1.Number + 1 equals t2.Number
join t3 in model.Numbers on t2.Number + 1 equals t3.Number
select new
{
t1 = t1.Number,
t2 = t2.Number,
t3 = t3.Number,
};
foreach (var res in triples)
{
Console.WriteLine(res.t1 + ", " + res.t2 + ", " + res.t3);
}
}
但是当我在管理工作室中比较结果查询时,它们会生成相同的执行计划,并执行完全相同的时间。我只有这个有限的数据集,你可以比较你的数据集的性能,如果它更大,并选择最好的,如果它们不同。
答案 3 :(得分:0)
以下代码将找到每个“root”。
var query = this.commercialRepository.GetQuery();
var count = 2;
for (int i = 0; i < count; i++)
{
query = query.Join(query, outer => outer.Index + 1, inner => inner.Index, (outer, inner) => outer);
}
var dummy = query.ToList();
它只会找到每个组中的第一个项目,因此您必须修改查询以记住其他项目,或者您可以根据您拥有根的事实和您知道的哪些索引来进行查询。得到。对不起,我不得不把它包起来,但也许它有点帮助。
PS。如果count为2,就像在这种情况下,它意味着如果找到3的组。