我有具体结果上方的选择:如何获得数量范围内的最大顺序?
1 2
1 3
1 5
1 6
1 9
1 10
1 11
1 13
1 14
1 16
1 18
1 20
1 23
1 24
1 25
我想找到的是发生在结果上最长的增加,由一链。
例如,我知道3是来自最后3个结果(23,24,25是3连续)的数字范围内的最大长度序列。
我有具体结果上方的选择:如何获得数量范围内的最大顺序?
1 2
1 3
1 5
1 6
1 9
1 10
1 11
1 13
1 14
1 16
1 18
1 20
1 23
1 24
1 25
我想找到的是发生在结果上最长的增加,由一链。
例如,我知道3是来自最后3个结果(23,24,25是3连续)的数字范围内的最大长度序列。
一个序列将具有数字与顺序排序之间的差异是恒定的属性。在SQL的大多数方言中,您都有一个名为row_number()
的函数,它可以分配连续的数字。
我们可以利用这个观察来解决问题:
select (num - seqnum), count(*) as NumInSequence
from (select t.*, row_number() over (order by num) as seqnum
from t
) t
group by (num - seqnum)
这给每个序列。要获得最大值,请使用max()
与子查询或某个版本的limit
/top
。在SQL Server中,例如,你可以这样做:
select top 1 count(*) as NumInSequence
from (select t.*, row_number() over (order by num) as seqnum
from t
) t
group by (num - seqnum)
order by NumInSQuence desc
+1优雅而简洁! – 2013-04-30 18:00:24
使用这篇文章作为主查询: http://www.xaprb.com/blog/2006/03/22/find-contiguous-ranges-with-sql/
只需添加计算的差列,并选择MAX()。
SELECT MAX(seq.end - seq.start)
FROM (
select l.id as start,
(
select min(a.id) as id
from sequence as a
left outer join sequence as b on a.id = b.id - 1
where b.id is null
and a.id >= l.id
) as end,
from sequence as l
left outer join sequence as r on r.id = l.id - 1
where r.id is null;
) AS seq
@戈登给出了一个明亮而又简洁的答案。不过,我认为递归实现也可能有用。下面是递归CTE的一个非常有用的文章:http://msdn.microsoft.com/en-us/library/ms186243(v=sql.105).aspx
-- This first CTE is unnecessary because you presumably already have
-- your data. But I wanted to include it to make it easier test.
WITH myNumbers AS (
SELECT *
FROM (
VALUES
(2),
(3),
(5),
(6),
(9),
(10),
(11),
(13),
(14),
(16),
(18),
(20),
(23),
(24),
(25)
) AS x (num)
),
-- To get my sequences I recurse until there is no num + 1 in my set
mySequences AS (
-- Anchor member definition: Create the first invocation
SELECT v.num, 0 AS iteration, v.num AS previous, v.num AS start
FROM myNumbers v
UNION ALL
-- Recursive member definition: Recurse until value + 1 does not exist
SELECT s.num + 1, s.iteration + 1 AS iteration, s.num AS previous, s.start
FROM mySequences s -- Notice that we can reference the CTE within itself
JOIN myNumbers v
ON v.num = s.num + 1
)
-- I must increment by 1 because I chose to start my recursion at 0
SELECT MAX(iteration + 1)
FROM mySequences
递归查询类似于编写
public int GetSequenceLength(int start, int iteration, int[] myNumbers)
{
if (myNumbers.Contains(start + 1))
{
return GetSequenceLength(start + 1, iteration + 1, myNumbers);
}
return iteration;
}
foreach (var myNumber in myNumbers)
{
var sequenceLength = GetSequenceLength(myNumber, 0, myNumbers) + 1;
Console.WriteLine(myNumber + " : " + sequenceLength);
}
它真的不清楚你问。例如,“顺序”是一个形容词,但你似乎将它用作名词,所以它很不确定你的意思。 – RBarryYoung 2013-04-30 16:14:41
很难理解你在问什么。我们如何解释你的结果?你在寻找什么样的序列?你怎么知道3是'最大顺序插件'? – 2013-04-30 16:14:47
我认为OP试图做的是在结果中找到连续的'增加1'的序列。例如,最后的23,24,25(这是3来自哪里,连续有3个做链) - 他们想要找出的是结果集中最长的这种链的时间长度。 – PhonicUK 2013-04-30 16:18:06