2017-01-08 3 views
1

В моем предложении WHERE я использую случайную функцию для получения случайного числа между 1 и 5. Однако результат всегда пуст без каких-либо ошибок.Использование функции Random в выражении WHERE

Здесь:

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

Execute 'выбрать (случайные() * 5 + 1)' несколько раз, и вы можете увидеть проблему. Я сомневаюсь, что любое из значений, которые вы увидите, будет равно любым значениям «Exam.exam». –

+1

Вы должны задать другой вопрос с данными образца и желаемыми результатами. Этот код, вероятно, не тот, который вы хотите сделать. –

ответ

2

От Docs

случайной()

случайной функции() возвращает псевдослучайное число между -9223372036854775808 и +9223372036854775807.

Следовательно, ваше случайное значение не находится между 0 и 1, как вы предполагали, и, следовательно, нет строк.

Вы можете получить его между 0 и 1, разделив его на 2 × 9223372036854775808 и добавив 0.5 к нему.

random()/18446744073709551616 + 0.5 

Итак, ваш где положение становится:

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) 
+0

Благодарим вас за объяснение. Но когда я использую предложение Where, я все равно не получаю никакого результата. –

+0

Я обновил ответ, просто включив 'round()', вы можете попробовать? – GurV

+0

Да, теперь он отображает несколько строк, но с несколькими значениями экзамена (2,3,4,5). Но мне просто нужны результаты только для одного значения случайного экзамена (например, 1). Есть ли проблема с предложением Where? –

0

Я отвечу на это вопрос с использованием Vertica в качестве базы данных.

Vertica имеет функцию RANDOM(), которая возвращает случайное число двойной точности между 0 и 1 и функцию RANDOMINT(<*integer*>), которая возвращает целое число от 0 до *<integer>*-1. Я буду использовать RANDOMINT(5) для этого примера.

Как общее предложение - Изолируйте свою конкретную проблему в своем вопросе. Соединения в вашем запросе не являются частью проблемы. И используйте примерную таблицу, как в приведенном ниже коде.

Как указывалось в некоторых предыдущих ответах, RANDOMINT(5) вернет новое случайное целое число от 0 до 4 для каждой строки, считанной из таблицы exam.

Смотрите здесь:

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 (общее выражение таблицы, так как я также использую его для генерации данных образца), сделайте это также в общем табличном выражении, которое я называю 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 

В качестве альтернативы вы можете пойти SELECT id,exam,exam_res FROM exam INNER JOIN search_exam USING(exam).

Счастливые игры - Marco здравомыслящего