有一个courses
表 ,有: student (学生) 和 class (课程)。
请列出所有超过或等于5名学生的课。
例如,表:
+---------+------------+
| student | class |
+---------+------------+
| A | Math |
| B | English |
| C | Math |
| D | Biology |
| E | Math |
| F | Computer |
| G | Math |
| H | Math |
| I | Math |
+---------+------------+
应该输出:
+---------+
| class |
+---------+
| Math |
+---------+
Note:
学生在每个课中不应被重复计算。
我想的是先将重复的学生去掉,再通过class分组,做完这两件事情产生一个新表,在这个新表里面查询分组之后学生的个数是否大于等于5;
select class from courses group by class having count(distinct student) >= 5 #先分组,再去重学生
select a.class from (select distinct * from courses) a group by a.class having count(a.class) >= 5
having的用法
having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句前。而 having子句在聚合后对组记录进行筛选。
还有其他两种做法:
#共三种写法
#最朴实的写法,共三层查询,先利用 DISTINCT 去掉重复记录得到表 A,再利用 GROUP BY 为 CLASS 分组,然
#后用 COUNT() 统计每组个数得到表 B,最后在最外层限定数量 >=5 查到结果
SELECT B.CLASS #最外层
FROM (SELECT A.CLASS,COUNT(A.CLASS) C #第二层查询,得到具有 CLASS、COUNT(CLASS) 的表 B
FROM (SELECT DISTINCT * #第三层查询,去重得到表 A
FROM COURSES) A
GROUP BY A.CLASS) B #分组
WHERE B.C >= 5; #条件
#稍微优化,两层查询,主要是因为用了 HAVING 省了一层查询
SELECT A.CLASS #最外层
FROM (SELECT DISTINCT * #第二层查询,去重得到表 a
FROM COURSES) A
GROUP BY A.CLASS #分组
HAVING COUNT(A.CLASS) >= 5; #利用 COUNT() 计算每组个数并筛选
#极致优化,一层查询,利用 GROUP BY 为 CLASS 分组后,直接用 COUNT() 统计每组学生个数,在统计前先用
#DISTINCT 去掉重复学生
SELECT CLASS
FROM COURSES
GROUP BY CLASS #分组
HAVING COUNT(DISTINCT STUDENT) >= 5; #利用 COUNT() 统计每门课 STUDENT 的个数,同时利
#用 DISTINCT 去掉重复学生
某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 LED显示板做电影推荐,上面公布着影评和相关电影描述。
作为该电影院的信息部主管,您需要编写一个 SQL查询,找出所有影片描述为非 boring
(不无聊) 的并且 id 为奇数 的影片,结果请按等级 rating
排列。
例如,下表 cinema
:
+---------+-----------+--------------+-----------+
| id | movie | description | rating |
+---------+-----------+--------------+-----------+
| 1 | War | great 3D | 8.9 |
| 2 | Science | fiction | 8.5 |
| 3 | irish | boring | 6.2 |
| 4 | Ice song | Fantacy | 8.6 |
| 5 | House card| Interesting| 9.1 |
+---------+-----------+--------------+-----------+
对于上面的例子,则正确的输出是为:
+---------+-----------+--------------+-----------+
| id | movie | description | rating |
+---------+-----------+--------------+-----------+
| 5 | House card| Interesting| 9.1 |
| 1 | War | great 3D | 8.9 |
+---------+-----------+--------------+-----------+
此题比较简单,使用select where order by就可以查出来,答案如下
select id,movie,description,rating from cinema where description != 'boring' and id%2 = 1 order by rating desc
Given a table salary, such as the one below, that has m=male and f=female values. Swap all f and m values (i.e., change all f values to m and vice versa) with a single update query and no intermediate temp table.
For example:
| id | name | sex | salary |
|----|------|-----|--------|
| 1 | A | m | 2500 |
| 2 | B | f | 1500 |
| 3 | C | m | 5500 |
| 4 | D | f | 500 |
After running your query, the above salary table should have the following rows:
| id | name | sex | salary |
|----|------|-----|--------|
| 1 | A | f | 2500 |
| 2 | B | m | 1500 |
| 3 | C | f | 5500 |
| 4 | D | m | 500 |
---------------------
update salary set sex = case when ‘f’ then ‘m’ else ‘f’ end
更多关于case的知识请参阅:https://www.cnblogs.com/clphp/p/6256207.html