简体   繁体   English

跨多个表的SQL连接

[英]SQL Joins across multiple tables

I am building an online survey system for which I wish to produce statistics. 我正在构建一个在线调查系统,希望为其生成统计数据。 I want query based on the gender of the user. 我想根据用户的性别进行查询。 I have the following tables: 我有以下表格:

  • survey_question_options survey_question_options
  • survey_answer survey_answer
  • users 使用者

I have constructed the following query so that it brings back a null response where there are no answers to the question: 我构造了以下查询,以便在没有问题答案的情况下返回空响应:

SELECT COUNT(sa.option_id) AS answer , so.option_label
FROM survey_answer sa 
RIGHT JOIN survey_question_options so 
        ON sa.option_id = so.option_id AND 
           sa.record_date>='2011-09-01' AND 
           sa.record_date<='2012-08-01'
LEFT JOIN users u 
       ON (sa.uid = u.uid AND u.gender='F')
WHERE so.question_id=24
GROUP BY so.option_label
ORDER BY so.option_id ASC

My query returns the following results set: 我的查询返回以下结果集:

0 Red
1 Yellow
0 Blue
0 Green

However, the gender condition in the LEFT JOIN appears to be ignored in the query. 但是,左联接中的性别条件在查询中似乎被忽略。 When I change the gender to 'M' the same result is returned. 当我将性别更改为“ M”时,将返回相同的结果。 However, the expected result would be 0 for everything. 但是,所有结果的预期结果均为0。

I am not sure where I am going wrong. 我不确定我要去哪里错。 Please help. 请帮忙。

Thanks in advance. 提前致谢。

Well, you are doing a COUNT on a column from the main table, so the gender condition on the LEFT JOIN won't affect the result. 好吧,您正在对主表中的列执行COUNT操作,因此LEFT JOIN上的性别条件不会影响结果。 You should do the COUNT on a column from the users table. 您应该对users表中的列执行COUNT I'm not sure if this is what you want, but you should try: 我不确定这是否是您想要的,但是您应该尝试:

SELECT COUNT(u.uid) AS answer , so.option_label
FROM survey_answer sa 
RIGHT JOIN survey_question_options so 
        ON sa.option_id = so.option_id AND 
           sa.record_date>='2011-09-01' AND 
           sa.record_date<='2012-08-01'
LEFT JOIN users u 
       ON (sa.uid = u.uid AND u.gender='M')
WHERE so.question_id=24
GROUP BY so.option_label
ORDER BY so.option_id ASC

The left join to the users table is evaluated after the join to the answer table - so although the user record is not returned if the user is the wrong gender, the answer record will be returned (regardless of the user's gender). 在联接到答案表之后评估到用户表的左联接-因此,如果用户性别错误,虽然不会返回用户记录,但是返回答案记录(无论用户的性别如何)。 Try: 尝试:

SELECT COUNT(sa.option_id) AS answer , so.option_label
FROM (select a.option_id
      from survey_answer a
      JOIN users u ON a.uid = u.uid AND u.gender='F'
      where a.record_date>='2011-09-01' AND 
            a.record_date<='2012-08-01') sa
RIGHT JOIN survey_question_options so 
        ON sa.option_id = so.option_id
WHERE so.question_id=24
GROUP BY so.option_label
ORDER BY so.option_id ASC

You're putting your condition in the wrong block. 您将状况置于错误的位置。 Since you're performing a LEFT JOIN , (which is a left-bound outer join) everything in the left table (the main table) is selected, together with the data from the joined table, where applicable . 由于您正在执行LEFT JOIN (这是左边界外部 LEFT JOIN ),因此会选择左表(主表)中的所有内容,以及来自联接表的数据( 如果适用) What you want is to add the data from all users and then restrict the full output of the query. 您想要的是添加所有 users的数据,然后限制查询的完整输出。 What you've actually done is add the user data from only the female users and then displayed all data. 您实际上所做的是仅添加女性用户的用户数据,然后显示所有数据。

Sounds technical, but all you have to do is move the AND u.gender='F' into the main WHERE clause instead the ON clause. 听起来是技术性的,但您要做的就是将AND u.gender='F'移到主WHERE子句中,而不是ON子句中。 That will cause SQL to only select the rows for female users after the JOIN has taken place. 这将导致SQL 执行JOIN 之后仅为女性用户选择行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM