我怎样才能整理这个SQL查询?

时间:2017-03-18 18:37:58

标签: sql

我有一个名为questions的表格,其中包含useridquestionid列,因此表格中的一行表示具有该userid的用户已回答了某个特定内容题。我想写一个查询来为表中的每个用户返回一个未答复的问题。

一个例子是:

userid | questionid
-------------------
1      | 3
1      | 4
2      | 1
2      | 4
3      | 2

我想要回归

userid | questionid
-------------------
1      | 1
2      | 2
3      | 1

从原始表中您可以推断出可用的问题是1,2,3和4.用户1只回答了问题3和4,所以我想建议回答问题1,用户2已回答问题1所以我想要建议他们回答问题2,等等。

我有以下内容:

SELECT q1.userid, 
(SELECT MIN(q2.questionid)
   FROM questions q2
  WHERE questionid NOT IN 
          (SELECT q3.questionid 
             FROM questions q3 
            WHERE q3.userid = q1.userid))
FROM questions q1

但这让我感到非常凌乱/低效。有没有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:0)

您可以通过以下方式返回所有未答案的问题:

SELECT u.userid, uq.questionid
FROM users u CROSS JOIN
     questions q LEFT JOIN
     userquestions uq
     ON uq.userid = u.userid and uq.questionid = q.questionid
WHERE uq.userid is null;

(注意:我修改了表名,使它们更有意义。名为questions的表不应该是联结表。)

但是,如果您只想为每个用户使用一个,我会建议一个相关的子查询:

select u.*,
       (select q.questionid
        from questions q left join
             userquestion uq
             on uq.questionid = q.questionid and
                uq.userid = u.userid
        where uq.userid is null
        order by rand()  -- strictly optional
        limit 1
       ) as random_unasked_question
from users u;

答案 1 :(得分:0)

我会按如下方式处理此问题(SQL Server)。公用表格表达式q和u实际上应该是表格(一个表格仅用于问题,一个表格仅供用户使用,保留原始"问题"表格用于模拟它们之间的多对多关系)。 unanswered cte计算问题用户和实际表格的完整笛卡尔积之间的集合差异。

; with 
q as (select distinct questionid from questions)
, u as (select distinct userid from questions)
, unanswered as (
select u.userid, q.questionid 
from u, q
except
select questions.userid, questions.questionid
from questions
    )
select userid, min(questionid)
from unanswered
group by userid