Richard, Say, that's really good! I'm still not used to taking advantage of those variables. Clever. Also, I think you can remove all but the rows showing gaps by adding a group by and having clause...
select id,@b:=IF(id=@a+1,id,concat(@a+1,"..",id-1)) range,@a:=id, @flag:=IF(@b=id,id,"MISSING") from seq group by id having id <> range; > -----Original Message----- > From: Richard Clarke [mailto:[EMAIL PROTECTED]] > Sent: Thursday, May 30, 2002 7:48 PM > To: [EMAIL PROTECTED] > Subject: Re: Finding holes in autoinc sequences > > > Or another approach could be (using same example tables) > > mysql> set @a:=0; set @b:=0; set @c:=0; > mysql> select > id,@b:=IF(id=@a+1,id,concat(@a+1,"..",id-1)),@a:=id,@flag:=IF( > @b=id,id,"MISS > ING") from seq; > +----+-------------------------------------------+--------+--- > -------------- > --------------+ > | id | @b:=IF(id=@a+1,id,concat(@a+1,"..",id-1)) | @a:=id | > @flag:=IF(@b=id,id,"MISSING") | > +----+-------------------------------------------+--------+--- > -------------- > --------------+ > | 1 | 1 | 1 | 1 > | > | 2 | 2 | 2 | 2 > | > | 3 | 3 | 3 | 3 > | > | 4 | 4 | 4 | 4 > | > | 5 | 5 | 5 | 5 > | > | 6 | 6 | 6 | 6 > | > | 7 | 7 | 7 | 7 > | > | 8 | 8 | 8 | 8 > | > | 9 | 9 | 9 | 9 > | > | 12 | 10..11 | 12 | MISSING > | > | 13 | 13 | 13 | 13 > | > | 14 | 14 | 14 | 14 > | > | 15 | 15 | 15 | 15 > | > | 16 | 16 | 16 | 16 > | > | 17 | 17 | 17 | 17 > | > | 18 | 18 | 18 | 18 > | > | 19 | 19 | 19 | 19 > | > | 22 | 20..21 | 22 | MISSING > | > | 24 | 23..23 | 24 | MISSING > | > | 25 | 25 | 25 | 25 > | > | 26 | 26 | 26 | 26 > | > | 27 | 27 | 27 | 27 > | > | 28 | 28 | 28 | 28 > | > | 29 | 29 | 29 | 29 > | > +----+-------------------------------------------+--------+--- > -------------- > --------------+ > 24 rows in set (0.00 sec) > > To get the MISSING entries you would need to create a > temporary table from > that query then select where the @flag column = "MISSING". > Maybe this is more efficient than the join previously suggested. > Maybe mysql team would let HAVING be applied to the > 'variably' created rows > you could then add having flag_alias = "MISSING" project out > just the rows > that are missing (saving the need for temporary tables). > > you could also plug the 10..11 20..21 etc statements into a > perl foreach > loop (if you were using perl) to automatically create the > inner numbers. > > Ric > > p.s. maybe there is a way of tricking it into using a having > statement to > project out the "MISSING" rows. > > > ----- Original Message ----- > From: "Kevin Fries" <[EMAIL PROTECTED]> > To: "'mos'" <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]> > Sent: Thursday, May 30, 2002 10:56 PM > Subject: RE: Finding holes in autoinc sequences > > > > A simple and fast way to find the gaps is to use a self > LEFT JOIN, such > as: > > > > select a.id from seq a left join seq b on a.id + 1 = b.id > > where b.id is null; > > > > > > The result set will show any row in seq where there was no > record with ID > > one greater than that record's value. > > You'll get back the last row, and any rows which don't have > a next-higher > > neighbor. > > > > To get my example above to work, use: > > > > create table seq ( id int auto_increment not null primary key); > > > > insert into seq values(); ** repeat to get rows 1..30. ** > > > > delete from seq where id between 10 and 11; > > delete from seq where id between 20 and 21; > > delete from seq where id = 23; > > > > select a.id from seq a left join seq b on a.id + 1 = b.id > > where b.id is null; > > > > +----+------+ > > | id | id | > > +----+------+ > > | 9 | NULL | > > | 19 | NULL | > > | 22 | NULL | > > | 30 | NULL | > > +----+------+ > > > > Note that this doesn't show where the gaps end. You can > further enhance > the > > query by looking backward as well...getting fancy output: > > > > select a.id, case when c.id is null and b.id is null then > '<>' else (case > > when c.id is null then '<' else (case when b.id is null > then '>' else '' > > end) end) end gaps > > from seq a left join seq b on a.id + 1 = b.id left join seq > c on a.id - 1 > = > > c.id > > where b.id is null or c.id is null; > > > > +----+------+ > > | id | gaps | > > +----+------+ > > | 1 | < | > > | 9 | > | > > | 12 | < | > > | 19 | > | > > | 22 | <> | > > | 24 | < | > > | 30 | > | > > +----+------+ > > > > Note here that there's a gap between 9 and 12, between 19 > and 22, and > > between 22 and 24. > > There's also a gap before 1, and one after 30, but this > just tells us > where > > the range ends. > > > > nulled Outer joins are very handy. > > > > Kevin Fries > > > > > > > > > > > > > -----Original Message----- > > > From: mos [mailto:[EMAIL PROTECTED]] > > > Sent: Thursday, May 30, 2002 1:18 PM > > > To: [EMAIL PROTECTED] > > > Subject: Finding holes in autoinc sequences > > > > > > > > > I'm going to be tackling this problem in a few days and I > > > wanted to bounce > > > it off of a few MySQL heads first to see if it generates any > > > ideas. (or > > > sparks?<g>) > > > > > > Here's is the problem. I have an auto-inc column and rows > > > will get deleted > > > from the table and of course it will create a hole in the > > > sequence which is > > > fine. But I want to track which rows have been deleted by > finding the > > > holes. (I will probably keep track of the deleted rows > as they get > > > deleted, but occasionally I will need to verify this by > > > scanning the table.) > > > > > > Example: > > > > > > Original squence of Rcd_Id: 1,2,3,4,5,6,7,8,9,10 > > > > > > After deleting rows 5 and 9 we get: > > > Rcd_Id: 1,2,3,4,6,7,8,10 > > > > > > Now is there any SQL statement that I can use to quickly and > > > efficiently > > > find the 2 missing rows in this example? The only thing I've > > > come up with > > > is to write a PHP program to loop through the Rcd_Id's in > > > order and see > > > which ones are missing (the query would fetch 10k rows at a > > > time so it > > > doesn't consume too much memory). The table could get rather > > > large (>1m > > > rows) and I need something that doesn't consume a lot of > > > memory or time. > > > Does anyone have any ideas? TIA > > > > > > Mike > > > > > > > > > > > > > --------------------------------------------------------------------- > > Before posting, please check: > > http://www.mysql.com/manual.php (the manual) > > http://lists.mysql.com/ (the list archive) > > > > To request this thread, e-mail <[EMAIL PROTECTED]> > > To unsubscribe, e-mail > <[EMAIL PROTECTED]> > > Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php > --------------------------------------------------------------------- Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail <[EMAIL PROTECTED]> To unsubscribe, e-mail <[EMAIL PROTECTED]> Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php