择了同时修几门课程(100,200)也有的学生只选择了一门课程(300,400,500)。选修多门课程的学生,要选择一门课程作为主修,主修flag里面写入Y。只选择一门课程的学生,主修flag为N(实际上要是写入Y的话,就没有下面的麻烦事了,为了举例子,还请多多包含)。
现在我们要按照下面两个条件对这个表进行查询
只选修一门课程的人,返回那门课程的ID
选修多门课程的人,返回所选的主课程ID
简单的想法就是,执行两条不同的SQL语句进行查询。
条件
--条件:只选择了一门课程的学生
SELECT std_id, MAX(class_id) AS main_class
FROM Studentclass
GROUP BY std_id
HAVING COUNT(*) = 1;
执行结果
STD_ID MAIN_class
------ ----------
300 4
400 5
500 6
条件
--条件:选择多门课程的学生
SELECT std_id, class_id AS main_class
FROM Studentclass
WHERE main_class_flg = 'Y' ;
执行结果
STD_ID MAIN_class
------ ----------
100 1
200 3
如果使用Case函数,我们只要一条SQL语句就可以解决问题,具体如下所示
SELECT std_id,
CASE WHEN COUNT(*) = 1 --只选择一门课程的学生的情况
THEN MAX(class_id)
ELSE MAX(CASE WHEN main_class_flg = 'Y'
THEN class_id
ELSE NULL END
)
END AS main_class
FROM Studentclass
GROUP BY std_id;
运行结果
STD_ID MAIN_class
------ ----------
100 1
200 3
300 4
400 5
500 6
通过在Case函数中嵌套Case函数,在合计函数中使用Case函数等方法,我们可以轻松的解决这个问题。使用Case函数给我们带来了更大的自由度。
最后提醒一下使用Case函数的新手注意不要犯下面的错误
CASE col_1
WHEN 1 THEN 'Right'
WHEN NULL THEN 'Wrong'
END
在这个语句中When Null这一行总是返回unknown,所以永远不会出现Wrong的情况。因为这句可以替换成WHEN col_1 = NULL,这是一个错误的用法,这个时候我们应该选择用WHEN col_1 IS NULL。
有一张表table1 结构如下.
table1:
username action
--------------------------------
A CALL
A SEARCH
A SEARCH
B CALL
B SEARCH
A SEARCH
A VIDEO
B SEARCH
B VIDEO
A CALL
B VIDEO
--------------------------------
通过一条SQL语句得出下列统计数据:
table2
username CALL_TIMES SEARCH_TIMES VIDEO_TIMES
-------------------------------------------------------------------------------
A 2 3 1
B 1 2 2
-------------------------------------------------------------------------------
说明:
table.action 中所有可能的值都已知的,只有 CALL , SEARCH ,VIDEO 和 table2 的字段一一对应
MYSQL 语句:
select
t.username,
max(CASE T.action WHEN 'CALL' THEN T.NN ELSE 0 end) as CALL_TIMES,
max(CASE T.action WHEN 'SEARCH' THEN T.NN ELSE 0 end) as SEARCH_TIMES,
max(CASE T.action WHEN 'VIDEO' THEN T.NN ELSE 0 end) as VIDEO_TIMES
from
(select temp.username,temp.action,count(*) as NN
from temp
group by temp.username,temp.action) as T
group by T.username
select username,
max(decode(action,'CALL',NN,0)) AS CALL_TIMES ,
max(decode(action,'VID