获取 MySQL 列中的最小未使用值

Posted

技术标签:

【中文标题】获取 MySQL 列中的最小未使用值【英文标题】:Get minimum unused value in MySQL column 【发布时间】:2014-11-01 09:40:27 【问题描述】:

我有一个带有整数 ID 列的表。我想获得此列的最小未使用值。查询应该找到表 ID 中的第一个漏洞并获取其中的最小值。我会试着用一些例子来解释它。

示例 1:无孔表

在这种情况下,我有一个没有孔的表,查询应该简单地获取最小未使用值:应该得到:4

|id|
|1 |
|2 |
|3 |

示例 2:顶部有孔的桌子

在这种情况下,我们在顶部有一个洞(缺失值:1)。查询找到洞并获取其中的最小值:应该得到 1。

|id|
|2 |
|3 |
|4 |

同样在这种情况下,我们在顶部有一个洞,但里面有更多的缺失值(缺失值:1 和 2)。查询找到洞并获取其中的最小值:应该得到 1。

|id|
|3 |
|4 |
|5 |

示例 3:中间有洞的桌子

在这种情况下,我们在中间有一个洞(缺失值:2 和 3)。查询找到了洞并得到了其中的最小值:应该得到 2。

|id|
|1 |
|4 |
|5 |

示例 4:顶部和中间有孔的桌子

在这种情况下,我们有多个孔:一个在顶部(缺失值:1)和一个在中间(缺失值:3)。查询找到第一个洞并获取其中的最小值:应该得到 1。

|id|
|2 |
|4 |
|6 |

我已经尝试了this post 中提出的解决方案,但在我的情况下它没有按预期工作。有什么想法吗?

【问题讨论】:

【参考方案1】:

您可以创建一个只包含数字的表格。我在下面的查询中模拟这个表。然后你就可以离开加入这个表了。

SELECT
MIN(numbers.n) AS missing_value
FROM (SELECT 1 as n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) numbers
LEFT JOIN your_table yt ON numbers.n = yt.id
WHERE yt.id IS NULL

【讨论】:

此解决方案可能有效,但会迫使我创建一个包含所有数字的表格......从 0 到无限......我说的对吗? 子查询执行此操作,如果范围合理,则很容易扩展子查询以提供大范围(您使用几个子查询交叉连接在一起,每个查询的数字为 0 到9,然后以一个为单位,一个为十,一个为百等)【参考方案2】:

如果您在其他表中有从 1 到 n 的值,比如 t2,那么只需检查

select min(id1) from t2 where id1 not exist(select id from t1);

你会得到答案的;

【讨论】:

这甚至不是合法的mysql【参考方案3】:
SELECT min(unused) AS unused
FROM (
    SELECT MIN(t1.id)+1 as unused
    FROM yourTable AS t1
    WHERE NOT EXISTS (SELECT * FROM yourTable AS t2 WHERE t2.id = t1.id+1)
    UNION
    -- Special case for missing the first row
    SELECT 1
    FROM DUAL
    WHERE NOT EXISTS (SELECT * FROM yourTable WHERE id = 1)
) AS subquery

【讨论】:

像魅力一样工作!非常感谢@Barmar! @Barmar 我如何在此查询中包含其他 where 条件?例如,如果我想从 SubId: 10 的行集合中选择一个数字? 其他条件如何适合在 ID 序列中查找漏洞?如果 ID = 10 符合条件而 ID = 11 不符合条件,是否应该返回 11 @Barmar 很好,在将其链接到我的新question 后,我再次检查了此答案,否则如果没有@,我将看不到您的回复...不,我的意思是我希望查询可以使用也具有特定 customId 的行。因此,例如,该表可能包含从 1 到 10 的行,其中每个 customId 缺少 2,假设它是 1 和 2。总共将是 20 行,但是我只需要从 customId 的选择中进行选择1. 所以在这个例子中查询只能处理十行,并给出我想要的缺失值,而不是扫描整个表。【参考方案4】:

使用连接而不是 EXISTS 的方式略有不同:-

SELECT MIN(t1.id)
FROM 
(
    SELECT 1 AS id
    UNION ALL
    SELECT id + 1
    FROM yourTable
) t1
LEFT OUTER JOIN yourTable t2
ON t1.id = t2.id
WHERE t2.id IS NULL;

使用子查询的任何解决方案的缺点是它们不太可能使用任何索引

【讨论】:

哇,简单有效!非常感谢 +1 的帮助!!

以上是关于获取 MySQL 列中的最小未使用值的主要内容,如果未能解决你的问题,请参考以下文章

如何从 MySQL 列中缺失的有序值中获取最小值? [复制]

获取数组列中的最小值和最大值

mysql 列中的最低可用值

使用 CUDA Thrust 确定每个矩阵列中的最小元素及其位置

SQL:在一列中获取最小值和最大值

如何从 MySQL 列中的 JSON 文档中获取最新值?