1

在最一般的情况下,我有如下查询:

SELECT tutor_school.name, count(*), tutor_school.schoolid 

FROM tutor_school, tutor_attends, tutor_tutors_in 

WHERE 
tutor_school.schoolid = tutor_attends.schoolid and 
tutor_school.schoolid in ('1', '2', '3') and 
tutor_attends.userid=tutor_tutors_in.userid

group by tutor_school.schoolid LIMIT 0, 10

本质上,我想要:

学校名称,就读该学校任教的学生人数,Schoolid

我实际上得到的是

学校名称,该学校学生教授的所有科目的总和,schoolid——换句话说,如果学生 1 辅导 3 个科目,学生 2 辅导 5 个科目,那么我得到 8 而不是返回 2!

我已经意识到问题在于以下声明:

tutor_attends.userid=tutor_tutors_in.userid

这不是检查远程表中给定外键的存在,而是为该键的每个实例提供结果。

我想弄清楚的是如何绑定它以将其限制为简单地存在给定键,而不是键出现的次数。我知道我在我的 SQL 课程中看到过类似的案例,但我不记得解决方案是什么。

4

3 回答 3

2

安德鲁是正确的,这是他解决方案的一个具体示例(必须对您的表格设计做出假设):

SQL> SELECT * FROM tutor_school;

  SCHOOLID NAME
---------- --------------------
         1 School A
         2 School B
         3 School C


SQL> SELECT * FROM tutor_attends;

    USERID   SCHOOLID
---------- ----------
         1          1
         2          1
         3          2


SQL> SELECT * FROM tutor_tutors_in;

    USERID SUBJECT
---------- --------------------
         1 Math
         1 Science
         1 English
         2 English
         3 Math


SQL> SELECT tutor_school.name, COUNT(DISTINCT tutor_tutors_in.userid)
  2  FROM tutor_school, tutor_attends, tutor_tutors_in
  3  WHERE tutor_school.schoolid=tutor_attends.schoolid
  4  AND tutor_attends.userid=tutor_tutors_in.userid
  5  GROUP BY tutor_school.name
  6  /

NAME                 COUNT(DISTINCTTUTOR_TUTORS_IN.USERID)
-------------------- -------------------------------------
School A                                                 2
School B                                                 1
于 2011-10-04T23:49:00.877 回答
1

首先,您应该学习 JOIN 的 ANSI 语法。不推荐仅使用该WHERE子句。撇开这一点不谈,我什至不用EXISTS.

SELECT tutor_school.name, count(DISTINCT tutor_attends.userid), tutor_school.schoolid 

FROM tutor_school, tutor_attends, tutor_tutors_in 

WHERE 
tutor_school.schoolid = tutor_attends.schoolid and 
tutor_school.schoolid in ('1', '2', '3') and 
tutor_attends.userid=tutor_tutors_in.userid

group by tutor_school.schoolid LIMIT 0, 10

我对您的架构有点困惑的地方是我看到了连接表,但没有看到普通的旧tutor表。用一个来概念化查询可能更容易。

于 2011-10-04T23:27:15.340 回答
0

您需要的关系运算符是半联接(而不是联接)。从您对要求的自然语言陈述来看,我认为 usingEXISTS是最合适的

例如

SELECT tutor_school.name, count(*), tutor_school.schoolid 
FROM tutor_school, tutor_tutors_in 
WHERE 
tutor_school.schoolid = tutor_attends.schoolid and 
tutor_school.schoolid in ('1', '2', '3') and
exists (
        SELECT *
          FROM tutor_attends
         WHERE tutor_attends.userid = tutor_tutors_in.userid
       )
group by tutor_school.schoolid LIMIT 0, 10
于 2011-10-05T08:33:29.700 回答