FROM (SELECT 10000+ ROUND(RAND()*89999) AS NUM) AS SUBQ
WHERE NUM NOT IN (SELECT PHONE_NUMBER FROM PHONE);
但是,虽然这确实选择了一个介于10000和99999之间的数字,但它只能在之后检查它是否不存在。如果检查失败,查询将不返回任何内容,您必须重试(或者使用联合使其复杂化,这仍然不能提供绝对的保证)。 另一种可能是生成另一个表,其中所有数字都在10000到99999之间,然后运行 LEFT JOIN 请求右侧为空。然后你必须从结果中随机选择一个条目;我不确定,但在这种情况下,您可能需要运行order by rand(),然后运行limit 1来提取一条记录,然后可能选择90万条记录。这将是昂贵的(但见最后的答案)。 如果phone表几乎是空的,最有效的方法是使用存储过程并继续运行第一个查询(或者在生成之后执行一个检查),直到它成功为止,如果phone表是稀疏的,它应该在很少的尝试内完成。 否则,您可以用所有号码预先填充电话表(该表已被大量填充,因此这不是一个很大的额外成本),并添加一列声明该号码是“免费”的。然后从表中选择一个随机条目,条件是自由标记产生true。在这种情况下,你会想读这个答案。
3条答案
按热度按时间oknwwptz1#
@gordonlinoff answer的一个问题是,它可能不返回任何内容,而返回另一个表中不存在的数字。有两种方法可以解决这个问题:使用存储函数,或者使用数字表。以下是如何使用存储函数:
然后您的查询就变成
或者,您可以创建一个数字表
LEFT JOIN
在电话号码表中,只选择不匹配的行,然后按排序RAND()
以及使用LIMIT 1
只返回一个结果。但是请注意,如果没有索引,这可能会非常慢num
以及phone_number
.在这种情况下,您的查询将是:
nwlls2ji2#
你可以做:
zrfyljdw3#
不去上班。最接近的方法是这样,通过 Package 到子查询中来保护第一个查询:
但是,虽然这确实选择了一个介于10000和99999之间的数字,但它只能在之后检查它是否不存在。如果检查失败,查询将不返回任何内容,您必须重试(或者使用联合使其复杂化,这仍然不能提供绝对的保证)。
另一种可能是生成另一个表,其中所有数字都在10000到99999之间,然后运行
LEFT JOIN
请求右侧为空。然后你必须从结果中随机选择一个条目;我不确定,但在这种情况下,您可能需要运行order by rand(),然后运行limit 1来提取一条记录,然后可能选择90万条记录。这将是昂贵的(但见最后的答案)。如果phone表几乎是空的,最有效的方法是使用存储过程并继续运行第一个查询(或者在生成之后执行一个检查),直到它成功为止,如果phone表是稀疏的,它应该在很少的尝试内完成。
否则,您可以用所有号码预先填充电话表(该表已被大量填充,因此这不是一个很大的额外成本),并添加一列声明该号码是“免费”的。然后从表中选择一个随机条目,条件是自由标记产生true。在这种情况下,你会想读这个答案。