0

我不知道这是否是 SQL 功能......简而言之:我想要一个表中的行,在另一个表的数组/逗号分隔列表中找不到 id。更多信息如下:

设置是两个表;一个用户表和一个问题表。user-table 有一个名为 answersQuestions 的列,这是一个逗号分隔的列表,其中包含用户已回答的问题 ID。

我试图得到 4 个随机问题,每个问题都没有得到回答。

我如何通过 SQL 查询获得 4 个随机数

SELECT * FROM questions WHERE id >= RAND() * (SELECT MAX(id) FROM questions) LIMIT 4

但这只会返回 4 个随机问题,而不会考虑用户之前是否有过该问题。

如果我应该用 Javascript 来做,它看起来像这样

var questions = [1,2,3,4,5,6,7,8,9,10,11,12];
var answeredQuestions = [3,5,9,12];
var sqlReturn = [];

for (var i=0;i<4;i++) { 
  var randNo = 0;

  while (randNo == 0 || sqlReturn.indexOf(randNo) > -1 || answeredQuestions.indexOf(randNo) > -1) {
    randNo = Math.floor((Math.random()*questions.length)+1);
  }

  sqlReturn[i] = randNo;
}

document.write(sqlReturn);
4

3 回答 3

1

不太喜欢您的解决方案。您的底层数据库设计让您自己的事情变得更加困难。

您有两个表,一个代表用户,另一个代表问题。你真正需要的是一个连接这两个概念的表格,比如用户问题。

建议设计:-

create table `user-questions`
(
   user_id int,
   question_id int,
   answered datetime
)

记录答案的建议方法。

每次您的用户回答问题时,在用户问题中输入一行以表示用户已经回答了问题。

在这种结构下,解决你的具体问题,找到尚未回答的问题,变得微不足道。

-- Find a question that hasn't been answered by user id 22.
SELECT
  q.* 
FROM 
  `questions`
LEFT OUTER JOIN `user-questions` uq
ON q.question_id = uq.question_id
-- Just a sample user ID
AND uq.user_id = 22
WHERE
  uq.question_id IS NULL

我不每天玩 MySQL,所以请随时纠正任何错别字,SO'ers。不过,这种方法是合理的。

于 2013-01-16T10:05:06.713 回答
0

虽然 Paul 是正确的,但您确实应该重构您的数据库。以下应该使用您现有的结构来完成:

声明@askedIDs VARCHAR(2000)

SET @askedIDs =(从用户那里选择已回答的问题 UserID = @userID)

EXECUTE ('SELECT * FROM Questions WHERE ID NOT IN (' + @askedIDs +')')

于 2013-01-16T10:06:49.970 回答
0

该功能FIND_IN_SET将帮助您这样做

要获取给定用户的所有未回答问题:

SELECT *
  FROM questions
 WHERE NOT FIND_IN_SET( id, ( SELECT answered_questions 
                                FROM users 
                               WHERE id = 1 ) )

并且只得到 4 个随机未回答的问题:

  SELECT *
    FROM questions
   WHERE NOT FIND_IN_SET( id, ( SELECT answered_questions 
                                  FROM users 
                                 WHERE id = 1 ) )
ORDER BY RAND()
   LIMIT 4

SQL 小提琴演示

尽管您可以运行此程序,但您应该查看规范化并重新设计表结构。

于 2013-01-16T10:07:04.790 回答