分组查询规则:(group by)SELECT 中的列必须满足以下其一:
- 出现在
GROUP BY中(如deptno)。 - 被聚合函数包裹(如
MAX(sal))
,SELECT 中的非聚合列必须全部出现在 GROUP BY 中
非聚合列指的是未被聚合函数(如SUM、AVG、MAX、COUNT等)处理的列。
SELECT ename, sal FROM emp GROUP BY ename, sal; -- 同时按ename和sal分组 -- 结果等价于不分组(假设ename唯一),分组就没作用,等价于输出select ename, sal FROM emp
SELECT dept_id, -- GROUP BY中的列 AVG(salary) -- 聚合函数(不在GROUP BY中) FROM employees GROUP BY dept_id;
case when then 两种模式
简单模式
SELECT CASE dept_id WHEN 1 THEN '技术部' WHEN 2 THEN '市场部' WHEN 3 THEN '销售部' ELSE '未知部门' END AS dept_name FROM employees;
核心:先计算 expression 的值,再将其与每个 WHEN 后的 value 进行等值比较。
搜索模式
sql
SELECT emp_name, salary, CASE WHEN salary > 3000 THEN '高级' WHEN salary > 2000 AND salary <= 3000 THEN '中级' WHEN salary <= 2000 THEN '初级' ELSE '未知' END AS level FROM employees;
- 核心:直接在
WHEN后写条件表达式,按顺序判断每个条件的真假。
对比项 |
简单模式 |
搜索模式 |
表达式位置 |
后必须有一个表达式(如列名) |
后无表达式,直接写 |
条件类型 |
后只能是值(用于等值比较) |
后是条件表达式(如 ) |
比较逻辑 |
固定为 |
支持任意条件(如 , , , 等) |
示例 |
|
|
简单模式,只能等值比较,搜索模式可以进行判断;简单模式 case后要加列名,搜索模式则是直接case 后面接when
if写法(case-when-then可以完全替代)
SELECT score, IF(score >= 60, '及格', '不及格') AS status FROM exams;
聚合函数 只能放在select之后(放列名的地方)或者having之后,而having必须与groupby一起使用(having是对分组之后的结果进行筛选)
MySQL 的 ONLY_FULL_GROUP_BY 模式 下,是的 —— 只要 SELECT 中包含 聚合函数 和 非聚合列,则 非聚合列必须全部包含在 GROUP BY 子句中(某列通过 函数依赖 与 GROUP BY 中的列关联,则可省略。)。
循环递归(属性结构)
/** * 菜单名称 */ @Data @ApiModel("树形结构VO") public class TreeVo { // 字段定义 @ApiModelProperty(value = "菜单名称") private String label; /** * 菜单ID */ @ApiModelProperty(value = "菜单ID") private String value; /** * 子菜单 */ @ApiModelProperty(value = "子菜单") private List<TreeVo> children; } 循环调用,类似树形结构
[ { "label": "一级菜单A", "value": "1", "children": [ { "label": "二级菜单A-1", "value": "1-1", "children": [] // 空列表表示叶子节点 }, { "label": "二级菜单A-2", "value": "1-2", "children": [ { "label": "三级菜单A-2-1", "value": "1-2-1", "children": [] } ] } ] }, { "label": "一级菜单B", "value": "2", "children": [] } ]
<resultMap id="TreeVoResultMap(别名随意)" type="com.zzyl.nursing.vo.TreeVo"> ************** 外层:楼层************* // column 对应的字段名(数据库中的字段,要与下面的sql对应) //property 对应的实体类属性名 <id column="fid" property="value"></id> <result column="name" property="label"></result> ***************中层:房间******************************** <collection property="children" ofType="com.zzyl.nursing.vo.TreeVo"> <id column="rid" property="value"></id> <result column="code" property="label"></result> ************ 内层:床号*************** <collection property="children" ofType="com.zzyl.nursing.vo.TreeVo"> <id column="bid" property="value"></id> <result column="bed_number" property="label"></result> </collection> </collection> </resultMap> <select id="getRoomAndBedByBedStatus" resultMap="TreeVoResultMap"> select f.id fid, f.name, r.id rid, r.code, b.id bid, b.bed_number from floor f left join room r on f.id = r.floor_id left join bed b on r.id = b.room_id where b.bed_status = #{status} order by f.id, r.id, b.id </select>
片段引用(实现sql的复用)
<!-- 定义可复用的 SQL 片段 --> <sql id="selectNursingLevelVo"> SELECT id, level_name, level_code, description, create_time, update_time FROM nursing_level </sql> <!-- 使用该片段的查询 --> <select id="selectNursingLevelById" parameterType="Long" resultMap="NursingLevelResult"> <include refid="selectNursingLevelVo"/> WHERE id = #{id} </select> 实际执行: SELECT id, level_name, level_code, description, create_time, update_time FROM nursing_level WHERE id = #{id}