在WHERE子句中使用随机函数

时间:2017-01-08 12:13:27

标签: sql sqlite android-sqlite

在我的WHERE条款中,我使用随机函数得到1到5之间的随机数。但是结果总是为空而没有任何错误。

这是:

Select Question._id, question_text, question_type, topic, favorite,   
picture_text, picture_src, video_text, video_src, info_title, info_text, 
info_picture_src, topic_text
FROM Question 
LEFT JOIN Question_Lv ON Question._id = Question_Lv.question_id 
LEFT JOIN Info ON Question._id = Info.question_id 
LEFT JOIN Info_Lv ON Question._id = Info_Lv.question_id 
LEFT JOIN Picture ON Question._id = Picture.question_id 
LEFT JOIN Picture_Lv ON Question._id = Picture_Lv.question_id 
LEFT JOIN Video ON Question._id = Video.question_id 
LEFT JOIN Video_Lv ON Question._id = Video_Lv.question_id 
LEFT JOIN Topic ON Question.topic = Topic._id 
LEFT JOIN Topic_Lv ON Topic._id = Topic_Lv.topic_id 
LEFT JOIN Exam ON Question._id = Exam.question_id 
WHERE Exam.exam = (random() * 5+ 1)

这种情况下的随机函数是什么以及如何正确使用它?

2 个答案:

答案 0 :(得分:2)

来自Docs

  

随机()

     

random()函数返回一个伪随机整数   -9223372036854775808和+9223372036854775807。

因此您的随机值不是假设的0到1之间,因此没有行。

你可以用2×9223372036854775808将它除以0到1之间,并加0.5。

random() / 18446744073709551616 + 0.5

所以,你的where子句变为:

WHERE Exam.exam = ((random() / 18446744073709551616 + 0.5) * 5 + 1)

与:

相同
WHERE Exam.exam = 5 * random() / 18446744073709551616 + 3.5

此外,您可能需要对右侧计算的输出进行舍入,因此:

WHERE Exam.exam = round(5 * random() / 18446744073709551616 + 3.5)

答案 1 :(得分:0)

我将使用Vertica作为数据库来回答这个问题。

Vertica具有函数RANDOM(),它返回0到1之间的随机双精度数,以及函数RANDOMINT(<*integer*>),它返回0到*<integer>*-1之间的整数。我将在此示例中使用RANDOMINT(5)

作为一般建议 - 在您的问题中隔离您的具体问题。查询中的联接不是问题的一部分。并使用示例表,就像我在下面的代码中所做的那样。

正如之前的一些答案所示,RANDOMINT(5)将为从exam表中读取的每一行返回0到4之间的新随机整数。

见这里:

WITH exam(id,exam,exam_res) AS (
          SELECT  1,1,'exam_res_1' 
UNION ALL SELECT  2,2,'exam_res_2' 
UNION ALL SELECT  3,3,'exam_res_3' 
UNION ALL SELECT  4,4,'exam_res_4' 
UNION ALL SELECT  5,5,'exam_res_5' 
UNION ALL SELECT  6,1,'exam_res_1' 
UNION ALL SELECT  7,2,'exam_res_2' 
UNION ALL SELECT  8,3,'exam_res_3' 
UNION ALL SELECT  9,4,'exam_res_4' 
UNION ALL SELECT 10,5,'exam_res_5'
UNION ALL SELECT 11,1,'exam_res_1'
UNION ALL SELECT 12,2,'exam_res_2'
UNION ALL SELECT 13,3,'exam_res_3'
UNION ALL SELECT 14,4,'exam_res_4'
UNION ALL SELECT 15,5,'exam_res_5'
)
SELECT * FROM exam WHERE exam=RANDOMINT(5)+1
;
id|exam|exam_res
 3|   3|exam_res_3
 4|   4|exam_res_4
 5|   5|exam_res_5
 6|   1|exam_res_1
 7|   2|exam_res_2
 9|   4|exam_res_4
12|   2|exam_res_2

您需要做的是确保只调用一次随机数生成器。

如果您的数据库遵守ANSI 99标准并且支持WITH子句(公用表表达式,因为我也用它来生成示例数据),那么也可以在公用表表达式中执行此操作 - 我称之为{{1 }}:

search_exam

或者,您可以转到WITH search_exam(exam) AS ( SELECT RANDOMINT(5)+1 ) , exam(id,exam,exam_res) AS ( SELECT 1,1,'exam_res_1' UNION ALL SELECT 2,2,'exam_res_2' UNION ALL SELECT 3,3,'exam_res_3' UNION ALL SELECT 4,4,'exam_res_4' UNION ALL SELECT 5,5,'exam_res_5' UNION ALL SELECT 6,1,'exam_res_1' UNION ALL SELECT 7,2,'exam_res_2' UNION ALL SELECT 8,3,'exam_res_3' UNION ALL SELECT 9,4,'exam_res_4' UNION ALL SELECT 10,5,'exam_res_5' UNION ALL SELECT 11,1,'exam_res_1' UNION ALL SELECT 12,2,'exam_res_2' UNION ALL SELECT 13,3,'exam_res_3' UNION ALL SELECT 14,4,'exam_res_4' UNION ALL SELECT 15,5,'exam_res_5' ) SELECT id,exam,exam_res FROM exam WHERE exam=(SELECT exam FROM search_exam) ; id|exam|exam_res 1| 1|exam_res_1 6| 1|exam_res_1 11| 1|exam_res_1

快乐的比赛 - Marco the Sane