mysql将查询结果交并差

差集、交集、并集

1.两个集合的结构要一致,对应的字段数,字段类型
2.将两个集合用 UNION ALL 关键字合并,这里的结果是有重复的所有集
3.将上面的所有集 GROUP BY id
4.最后 HAVING COUNT(id)=1,等于1的意思是只出现了一次,所以这个是差集,如果等于2,那么就是交集

学生表

课程表

成绩表

老师表

学过01课程的同学信息

select st.* from student st 
left join score sc on st.s_id = sc.s_id
where sc.c_id='01'

学过02课程的同学信息

select st.* from student st 
left join score sc on st.s_id = sc.s_id
where sc.c_id='02'

差集

查询只学过编号为"01"或者只学过编号"02"课程的同学的信息

select a.* from (
select st.* from student st 
left join score sc on st.s_id = sc.s_id
where sc.c_id='01'
UNION ALL
select st.* from student st 
left join score sc on st.s_id = sc.s_id
where sc.c_id='02') as a GROUP BY a.s_id, a.s_name,a.s_birth,a.s_sex HAVING count(a.s_name)=1

结果如下:

交集

查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息

select a.* from (
select st.* from student st 
left join score sc on st.s_id = sc.s_id
where sc.c_id='01'
UNION ALL
select st.* from student st 
left join score sc on st.s_id = sc.s_id
where sc.c_id='02') as a GROUP BY a.s_id, a.s_name,a.s_birth,a.s_sex HAVING count(a.s_name)=2

结果如下

并集 UNION 可以去重

查询学过编号为"01"或者学过编号为"02"的课程的同学的信息

select st.* from student st 
left join score sc on st.s_id = sc.s_id
where sc.c_id='01'
UNION 
select st.* from student st 
left join score sc on st.s_id = sc.s_id
where sc.c_id='02'

结果如下:

写sql报错遇到一个问题

第一个解决方案 修改配置文件 重启mysql

sql_mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" 去掉 ONLY_FULL_GROUP_BY 参数 重启mysql

第二个解决方案 修改sql group by 后面把所有的字段都加上

ONLY_FULL_GROUP_BY是MySQL提供的一个sql_mode,通过这个sql_mode来提供SQL语句GROUP BY合法性的检查,在MySQL的sql_mode没有ONLY_FULL_GROUP_BY语义时。一条select语句,MySQL允许target list中输出的表达式是除聚集函数或group by column以外的表达式。ONLY_FULL_GROUP_BY的语义就是确定select target list中的所有列的值都是明确语义,简单的说来,在ONLY_FULL_GROUP_BY模式下,target list中的值要么是来自于聚集函数的结果
原文地址:https://www.cnblogs.com/lvshuizhicheng/p/14548413.html