这些是我的表格:
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'
请帮我解决问题。
答案 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扩展,有时称为“隐藏列”。您在select
或having
子句中的列既不是聚合键(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)
course
和professor
之间进行交叉联接,以获得课程和教授的所有组合; works
与(course, professor)
之间建立外部联接,以确定实际存在哪些SELECT course.*
FROM (course, professor) LEFT JOIN works USING (courseid, empid)
GROUP BY courseid
HAVING SUM(works.empid IS NULL) = 0
组合; 因此:
{{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);
其工作