Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect missing values in a (auto-incremented) sequence

Tags:

loops

mysql

I have a 'Port' INT column, which it's supposed to range from 30000 to 50000.

So, I have a Stored Procedure inserting values (Port is NOT NULL). So I have to choose 'manually' the value storing on that field. Problem is, altough I can insert incrementally (30000,30001,30002....) at a certain point some entries are deleted (it becames 30000, 30002, 30004.... ) so there are holes to be set.

I need to place in my SP a way to fit those holes (on the example I have they are 30001,30003 ....). My problem is how to check within the SP, if a certain value is already 'ocuppied'.

The I thought using LOOP from MySQL. Tried something like this:

CREATE PROCEDURE teste()
BEGIN
DECLARE p INT;
DECLARE aux INT;
SET p = 30000;

  label1: LOOP

    SELECT Port FROM Reg WHERE Port = p INTO aux;

    IF p = 50000 THEN
    LEAVE label1;
    END IF;


    IF aux IS NULL THEN -- aux-1 is not null, so I can verify the "next  miminum available position"
        aux = aux - 1;
        LEAVE label1;

    ELSE
        SET p = p + 1;
        ITERATE label1;


    END IF;

  END LOOP label1;

 RETURN aux;

END $$

My problem is obtaining a result value. If I place that RETURN statement I get the info that is only allowed on a FUNCTION. And the result from the SELECT is always null when I end the Loop.

What can I do?

like image 564
Tiago Avatar asked Feb 01 '26 22:02

Tiago


2 Answers

Here's how you can find missing values in your sequence.

SELECT a.id+1 AS start, MIN(b.id) - 1 AS end
    FROM seq AS a, seq AS b
    WHERE a.id < b.id
    GROUP BY a.id
    HAVING start < MIN(b.id)

Example output:

    +-------+------+
    | start | end  |
    +-------+------+
    |     4 |    4 |
    |     7 |    9 |
    +-------+------+

It means that in id sequence value 4 is missing, and also numbers from 7 to 9 (inclusively).

Adapt this code for your needs by replacing corresponding names.

like image 56
Sergio Tulentsev Avatar answered Feb 04 '26 14:02

Sergio Tulentsev


SELECT IFNULL(MIN(r1.Port) + 1, 30000) as minport
FROM Reg r1
LEFT JOIN Reg r2 ON r1.Port + 1 = r2.Port
WHERE r2.Port IS NULL:
like image 43
newtover Avatar answered Feb 04 '26 15:02

newtover



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!