2009-04-07 6 views
3

私はIDのテーブルを持っており、位置SQL内のグループ内で順不同の値を見つける方法は?

CREATE TABLE #MissingSequence (ID INT NOT NULL, Position INT NOT NULL) 
INSERT INTO #MissingSequence (ID,Position) 
SELECT 36,1 
UNION ALL SELECT 36,2 
UNION ALL SELECT 36,3 
UNION ALL SELECT 36,4 
UNION ALL SELECT 36,5 
UNION ALL SELECT 36,6 
UNION ALL SELECT 44,1 
UNION ALL SELECT 44,3 
UNION ALL SELECT 44,4 
UNION ALL SELECT 44,5 
UNION ALL SELECT 44,6 

私は何を見つけるしようとしています。この場合、IDによる位置のシーケンスのいずれかのブレークが44,1と44,3

の間に切れ目がある場合です

SELECT l.ID 
    ,Start_Position = MIN(l.Position) + 1 
    ,Stop_Position = MIN(fr.Position) - 1 
FROM #MissingSequence l 
LEFT JOIN #MissingSequence r 
    ON l.Position = r.Position - 1 
LEFT JOIN #MissingSequence fr 
    ON l.Position < fr.Position 
WHERE r.Position IS NULL 
    AND fr.Position IS NOT NULL 
GROUP BY l.ID 

をが、複数のID値がある場合、それは動作しません:

私が一緒に解析するために管理してきました。 1つのID、44しか存在しない場合は機能します。

思考、コメント、提案?

ありがとうございました!

+0

あなたはどのような出力をしたいと思います。ここでは

はnullで左の参加のアイデアを使用して(ANSI準拠)バージョンは、一番上の行と下の行を選択し、それらの間に何もないのチェック、です見る?許容される位置の最大値はありますか? – tpdi

+0

ポジションの最大数はありません...私が取り組んでいる全テーブルには、約12k IDレコード、ポジション3からx –

+0

の@Christopherが含まれています。 –

答えて

7

を使用することができます左自己結合は良い本能だったが、私は、凝集体がそれをカットしようとしているとは思わない、と確かにあなたがする必要があると思いますself-joinに一致ID句を含めます。

SELECT 
    above.ID AS ID, below.Position+1 AS Start_Position, above.Position-1 AS End_Position 
FROM MissingSequence AS above 
JOIN MissingSequence AS below 
    ON below.ID=above.ID AND below.Position<above.Position-1 
LEFT JOIN MissingSequence AS inbetween 
    ON inbetween.ID=below.ID AND inbetween.Position BETWEEN below.Position+1 AND above.Position-1 
WHERE inbetween.ID IS NULL; 

+----+----------------+--------------+ 
| ID | Start_Position | End_Position | 
+----+----------------+--------------+ 
| 44 |    2 |   2 | 
+----+----------------+--------------+ 
+0

これはちょうどそれについてだと思う... HAVINGは迷惑であるが、それは私が思い付いたよりも良い、ありがとう+1 [x] –

+0

ああ!もちろん、HAVINGなしでそれを行うことができます。上記のクエリを更新しました。もう少しうまくいくはずです。 – bobince

+0

すごい、それはそれを釘付け! –

2

このクエリは、スリップを発見し、有用であることを願っています。あなたはSQL 2005にある場合、あなたはCTE

SELECT ID, Position + 1 
FROM #MissingSequence t1 
WHERE (Position + 1) NOT IN (SELECT Position FROM #MissingSequence t2 WHERE t1.ID = t2.ID) 
AND Position <> (SELECT MAX(Position) FROM #MissingSequence t2 WHERE t1.ID = t2.ID) 
+0

これは、 – bobince

+0

ああ、大丈夫、確かに、 –

0
create database testing 
use testing; 
create table sequence (
    id int not null primary key 
); 

insert into sequence(id) values 
    (1), (2), (3), (4), (6), (7), (8), (9), 
    (10), (15), (16), (17), (18), (19), (20); 

select * from sequence 

Create PROCEDURE test_proce(@mode varchar(50)) 
AS 
BEGIN 
    declare @se int; 
    set @se=0; 
    set @se=(
     select top 1 t.id + 1 
     from sequence t 
     left join sequence x on x.id = t.id + 1 
     where x.id is null 
     order by t.id 
    ); 
    select * from sequence where id<@se; 
END 

exec test_proce 'mode' 
関連する問題