MySQL Left Join with conditional

时间:2010-08-25 10:13:55

标签: sql mysql

看起来非常简单我有一个表'问题',它存储了所有问题的列表,以及位于'问题'和'用户'之间的多对多表格,名为'question_answer'。

是否可以执行一个查询以获取问题表中的所有问题以及用户已回答的问题,其中未回答的问题为NULL值

问题:

| id | question |

question_answer:

| id | question_id | answer | user_id |

我正在进行此查询,但条件是强制执行仅返回已回答的问题。我是否需要求助于嵌套选择?

SELECT * FROM `question` LEFT JOIN `question_answer`
ON question_answer.question_id = question.id
WHERE user_id = 14583461 GROUP BY question_id

4 个答案:

答案 0 :(得分:1)

如果user_id在外部连接到表中,则谓词user_id = 14583461将导致不返回user_id为空的任何行,即具有未解答问题的行。你需要说“user_id = 14583461或user_id为null”

答案 1 :(得分:0)

你不应该使用RIGHT JOIN吗?

SELECT * FROM question_answer RIGHT JOIN question ON question_answer.question_id = question.id
WHERE user_id = 14583461 GROUP BY question_id

答案 2 :(得分:0)

这样的事情可能会有所帮助(http://pastie.org/1114844

drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varchar(32) not null
)engine=innodb;

drop table if exists question;
create table question
(
question_id int unsigned not null auto_increment primary key,
ques varchar(255) not null
)engine=innodb;

drop table if exists question_ans;
create table question_ans
(
user_id int unsigned not null,
question_id int unsigned not null,
ans varchar(255) not null,
primary key (user_id, question_id)
)engine=innodb;

insert into users (username) values 
('user1'),('user2'),('user3'),('user4');

insert into question (ques) values 
('question1 ?'),('question2 ?'),('question3 ?');

insert into question_ans (user_id,question_id,ans) values
(1,1,'foo'), (1,2,'mysql'), (1,3,'php'),
(2,1,'bar'), (2,2,'oracle'),
(3,1,'foobar');

select
 u.*,
 q.*,
 a.ans
from users u
cross join question q
left outer join question_ans a on a.user_id = u.user_id and a.question_id = q.question_id
order by
 u.user_id,
 q.question_id;

select
 u.*,
 q.*,
 a.ans
from users u
cross join question q
left outer join question_ans a on a.user_id = u.user_id and a.question_id = q.question_id
where
 u.user_id = 2
order by
 q.question_id;

编辑:添加了一些统计/解释计划&运行时:

运行时:0.031(10,000个用户,1000个问题,350万个答案)

select count(*) from users
count(*)
========
10000 

select count(*) from question
count(*)
========
1000 

select count(*) from question_ans
count(*)
========
3682482 

explain
select
 u.*,
 q.*,
 a.ans
from users u
cross join question q
left outer join question_ans a on a.user_id = u.user_id and a.question_id = q.question_id
where 
 u.user_id = 256
order by
 u.user_id,
 q.question_id;


id  select_type table   type    possible_keys   key         key_len ref                         rows    Extra
==  =========== =====   ====    =============   ===         ======= ===                         ====    =====
1   SIMPLE          u   const   PRIMARY         PRIMARY         4   const                       1       Using filesort
1   SIMPLE          q   ALL                                                                     687 
1   SIMPLE          a   eq_ref  PRIMARY         PRIMARY         8   const,foo_db.q.question_id  1   

答案 3 :(得分:0)

将user_id谓词移动到连接条件中。这将确保返回question中的所有行,但仅返回question_answer中具有指定用户ID和问题ID的行。

SELECT * FROM question
    LEFT JOIN question_answer ON question_answer.question_id = question.id 
                              AND user_id = 14583461
ORDER BY user_id, question_id