检测(自动递增)序列中的缺失值

时间:2011-12-28 18:26:04

标签: mysql loops

我有一个'Port'INT列,它应该在30000到50000之间。

所以,我有一个存储过程插入值(Port is NOT NULL)。所以我必须选择“手动”存储在该字段上的值。问题是,尽管我可以在某一点逐步插入(30000,30001,30002 ....)一些条目被删除(它因为30000,30002,30004 ....)所以有空洞要设置。

我需要在我的SP中放置一个适合这些洞的方法(例如我有30001,30003 ......)。我的问题是如何在SP中检查,如果某个值已经'ocuppied'。

我想从MySQL使用LOOP。试过这样的事情:

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 $$

我的问题是获得结果值。如果我放置RETURN语句,我将获得仅在FUNCTION上允许的信息。当我结束循环时,SELECT的结果总是为空。

我该怎么办?

4 个答案:

答案 0 :(得分:5)

以下是您在序列中找到缺失值的方法。

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)

示例输出:

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

这意味着在id序列中缺少值4,并且数字从7到9(包含)。

通过替换相应的名称来调整此代码以满足您的需求。

答案 1 :(得分:2)

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:

答案 2 :(得分:1)

你能做这样的事吗?

SELECT
    MIN(Port + 1)
FROM
    Reg
WHERE
    Port + 1 NOT IN (
        SELECT Port FROM Reg WHERE Port > 0
    )
ORDER BY
    Port ASC

答案 3 :(得分:0)

只需将所有值从30000插入到50000(假设您在该字段上有唯一键)。在检测中,没有什么比数据库本身更快,无论值是否存在。