查询使用内部联接和拥有

时间:2014-02-01 18:55:20

标签: mysql

这些是我的表格:

mysql> select * from professor;
+-------+--------+--------+--------+------+
| empid | name   | status | salary | age  |
+-------+--------+--------+--------+------+
|     1 | Arun   |      1 |   2000 |   23 |
|     2 | Benoy  |      0 |   3000 |   25 |
|     3 | Chacko |      1 |   1000 |   36 |
|     4 | Divin  |      0 |   5000 |   32 |
|     5 | Edwin  |      1 |   2500 |   55 |
|     7 | George |      0 |   1500 |   46 |
+-------+--------+--------+--------+------+
6 rows in set (0.00 sec)

mysql> select * from works;
+----------+-------+---------+
| courseid | empid | classid |
+----------+-------+---------+
|        1 |     1 |      10 |
|        2 |     2 |       9 |
|        3 |     3 |       8 |
|        4 |     4 |      10 |
|        5 |     5 |       9 |
|        6 |     1 |       9 |
|        2 |     3 |      10 |
|        2 |     1 |       7 |
|        4 |     2 |       6 |
|        2 |     4 |       6 |
|        2 |     5 |       2 |
|        7 |     5 |       6 |
|        3 |     5 |       2 |
|        6 |     4 |      10 |
|        2 |     7 |       1 |
+----------+-------+---------+
15 rows in set (0.00 sec)

mysql> select * from course;
+----------+------------+--------+
| courseid | coursename | points |
+----------+------------+--------+
|        1 | Maths      |      5 |
|        2 | Science    |      1 |
|        3 | English    |      6 |
|        4 | Social     |      4 |
|        5 | Malayalam  |     20 |
|        6 | Arts       |     25 |
|        7 | Biology    |     20 |
+----------+------------+--------+
7 rows in set (0.00 sec)

问题是:

  

归还所有教授所教授的课程。

我尝试的查询是:

select course.coursename from
course inner join works
on course.courseid=works.empid
group by works.courseid
having works.empid in (select empid from professor);

我收到这样的错误:

  

'IN / ALL / ANY子查询'中的未知列'works.empid'

请帮我解决问题。

http://sqlfiddle.com/#!2/4b197/5

5 个答案:

答案 0 :(得分:2)

评论太长了。

首先,查询与您想要的一致。我只会解决这个错误。

错误非常有趣。简而言之,MySQL允许一些称为隐藏列的东西(如下所述)。但是,这些仅在having子句中包含select子句时才起作用。我不知道。

以下两个查询正确解析(我为了简洁而跳过中间部分):

select course.coursename, works.empid
. . .
having works.empid = 1;

select course.coursename, works.empid
. . .
having works.empid = 1;

然而,以下两个失败并出现同样的错误:

select course.coursename
. . .
having works.empid = 1;

select course.coursename
. . .
having works.empid = 1;

select子句中未提及该列的唯一区别。

发生的事情是您正在使用group by子句的MySQL扩展,有时称为“隐藏列”。您在selecthaving子句中的列既不是聚合键(course.courseid),也不是聚合函数(例如min(works.empid)group_concat(works.empid))。显然,MySQL只在having子句中已经在`select子句中时才识别这些列。在学习SQL的阶段,你不应该这样做。在documentation之后关闭这个扩展并转到ANSI标准行为:

  

要禁用MySQL GROUP BY扩展,请启用ONLY_FULL_GROUP_BY   SQL模式。这将启用标准SQL行为:未在中命名的列   GROUP BY子句不能在选择列表或HAVING子句中使用   除非包含在一个聚合函数中。

修复语法问题的方法是使用聚合函数,例如:

select course.coursename
. . .
having min(works.empid) = 1;

select course.coursename
. . .
having min(works.empid) = 1;

这将使您无法获得有效的查询,因为您的问题远非解决问题。但它会解决语法错误。

答案 1 :(得分:2)

除了你当前查询给你一个错误的原因,@ GordonLinoff详细解释了,一种方法来实现所需的结果

  

返回所有教授所教授的课程。

SELECT c.*
  FROM
(
  SELECT courseid
    FROM works
   GROUP BY courseid
  HAVING COUNT(DISTINCT empid) =
  (
    SELECT COUNT(*)
      FROM professor
  )
) q JOIN course c
    ON q.courseid = c.courseid

注意:感谢@eggyal,值得一提的是,此查询的操作假设参照完整性完整,意味着works表没有孤立记录(行{{ 1}}指的是empid表中不存在的行,并且在技术上返回由professor表中当前存在的相同数量的教授讲授的课程,在完整的参照完整性的情况下是我们正在寻找的课程。

输出:

| COURSEID | COURSENAME | POINTS |
|----------|------------|--------|
|        2 |    Science |      1 |

这是 SQLFiddle 演示

答案 2 :(得分:0)

  1. courseprofessor之间进行交叉联接,以获得课程和教授的所有组合;
  2. 在该works(course, professor)之间建立外部联接,以确定实际存在哪些SELECT course.* FROM (course, professor) LEFT JOIN works USING (courseid, empid) GROUP BY courseid HAVING SUM(works.empid IS NULL) = 0 组合;
  3. 按程序分组,并总结不存在的此类组合的数量;
  4. 仅对那些没有此类不存在的组合的组进行过滤。
  5. 因此:

    {{1}}

答案 3 :(得分:-1)

试试这个:

select c.coursename, w.empid from
course as c inner join works as w
on (c.courseid=w.empid)
group by w.courseid
having w.empid in (select p.empid from professor as p);

答案 4 :(得分:-3)

select course.coursename,works.courseid,works.empid from
course inner join works
on course.courseid=works.empid
group by works.courseid
having works.empid in (select empid from professor);

其工作