2

上記の特定の結果が選択されています。

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

私が見つけたいのは、結果で発生する最長の 1 ずつ増加するチェーンです。

たとえば、最後の 3 つの結果 (23、24、25 は 3 つ連続) から、この数値範囲の最大長シーケンスは 3 であることがわかっています。

4

3 に答える 3

5

数列には、数と連続した順序の違いが一定になるという特性があります。row_number()SQL のほとんどの方言には、連番を割り当てるという関数があります。

この観察結果を使用して、問題を解決できます。

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
于 2013-04-30T16:19:16.537 に答える
1

この記事をメインクエリとして使用: 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
于 2013-04-30T16:20:31.063 に答える
0

@Gordon は素晴らしい、より簡潔な答えを出しました。ただし、再帰的な実装も役立つと思います。再帰的 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);
}
于 2013-04-30T17:58:28.037 に答える