任何 SQL 来获取我的 MySQL 数据库表中未列出的第一个数字?前任:
表:用户
ID | Name | Number
------------------------
1 | John | 1456
2 | Phil | 345
3 | Jenny | 345612
在这种情况下,SQL 必须返回编号从 1 到 344 和 346 到 1455 和 1457 到 345611 的行列表
有什么建议么?也许有一些程序?
鉴于评论,我的第一种方法是使用“随机数”探测。这种方法假设:
Number
被索引;和方法:
N
在客户端随机选择(即1-10)个数字;Number IN (ns..)
或Number = n
; N=1
然后在这种情况下,大小N=1
可能“没问题”,并且实现起来最简单,尽管它需要至少 6 个数据库请求才能找到 6 个空闲号码。较大的N
将减少访问数据库的次数。
确保使用事务。
我喜欢@pst 的答案,但会建议另一种选择。
创建一个未分配数字的新表,在其中插入几千行左右。
向用户展示其中一些数字。
使用号码时,将其从未分配号码表中删除。
根据需要定期生成更多未分配的号码。
这些未分配数字的生成可以使用@pst 建议的随机方法,但是使用这种方法,您可以将生成未分配数字列表需要多长时间的不确定性转移到批处理任务中,而不必在用户等待时的前端。如果数字空间的使用是稀疏的,这可能不是问题,但随着更多的数字空间被使用,它成为一个更大的问题。
只需使用自动增量列。数据库将自动分配下一个号码。您甚至不需要知道插入时它是什么。只告诉用户他得到的号码,根本不给他选择。
SELECT 'start', 1 AS number FROM tableA
UNION
SELECT 'min', number - 1 number FROM tableA
UNION
SELECT 'max', number + 1 number FROM tableA
ORDER BY number
您可以在http://www.sqlfiddle.com/#!2/851de/6查看答案
然后,您可以在下次填充时对缺失的数字进行比较。
根据您的评论,以下方法可能对您有用。它并没有真正回答您的具体问题,但它可能满足您的要求。
我将假设您的要求不会改变(例如,向用户提供 6 个可能的 id 选择)。坦率地说,我认为这是一个奇怪的要求,但它产生了一些有趣的 SQL。:-)
这是我的方法:生成 10 个随机数。过滤掉数据库中已经存在的任何内容。向您的用户展示其中的 6 个随机数。与顺序 id 编号相比,随机 id 编号在事务性方面具有非常好的属性,因此如果您的应用程序变得流行,它应该可以很好地扩展。
SELECT
temp.i
FROM
(
SELECT 18 AS i -- 10 random
UNION SELECT 42 -- numbers.
UNION SELECT 88
UNION SELECT 191 -- Let's assume
UNION SELECT 192 -- you generated
UNION SELECT 193 -- these in the
UNION SELECT 1000 -- application
UNION SELECT 123456 -- layer.
UNION SELECT 1092930
UNION SELECT 9892919
) temp
LEFT JOIN
mytable ON (temp.i = mytable.i)
WHERE
mytable.i IS NULL -- filter out collisions
LIMIT
6 -- limit results to 6
SQL弹出测验时间!!!
WHERE mytable.i IS NULL
”过滤冲突?(提示mytable.i
:当它是主键时,它怎么可能是空的?)下面是一些测试数据:
CREATE TABLE mytable (i BIGINT PRIMARY KEY) ;
INSERT INTO mytable VALUES (88), (3), (192), (123456) ;
运行上面的查询,结果如下。请注意,88、192 和 123456 被过滤掉了,因为它们会与测试数据发生冲突。
+---------+
| i |
+---------+
| 18 |
| 42 |
| 191 |
| 193 |
| 1000 |
| 1092930 |
+---------+
以及如何生成这些随机数?可能 rand() * 9223372036854775807 会起作用。(假设你不想要负数!)