排序查询

一、语法

select 查询列表
from 表名
where 筛选条件
order by 排序列表【asc|desc】

二、特点

  1. asc:升序,如果不写默认升序。desc:降序。
  2. 排序列表支持单个字段、多个字段、函数、表达式、别名。
  3. order by的位置一般放在查询语句的最后(除了limit语句之外)。

常见函数

一、概述

功能:类似于java中的方法
好处:提高复用和隐藏实现细节
调用:select 函数名(实参列表);

二、单行函数

1、字符函数:

concat:连接
length: 长度
lpad: 左填充
rpad:右填充
trim: 左右去空格,或指定字符。
substr:截取,注意mysql中截取下标从1开始。
upper: 字母大写
lower: 字母小写
replace: 替换

2、数学函数:

ceil:向上取整
round:四舍五入
mod:取模
floor:向下取整
truncate:截断
rand:获取随机数,返回0~1之间的小数

3、日期函数

now:返回当前日期+时间
year:返回年
month:返回月
day:返回日
curdate:返回当前日期
curtime:返回当前时间
date_format:日期转换成字符串
str_to_date:将字符转换成日期
hour:小时
minute:分钟
second:秒
datediff:返回两个日期相差的天数
monthname:以英文形式返回月

4、其它函数

version:版本号
database:当前打开的数据库
user:当前用户
password(‘字符’):返回字符参数的密码形式。
md5(‘字符’):返回md5的加密形式。
ifnull:第一个参数为null,则用第二个参数代替。

5、流程控制函数

①if(条件表达式,表达式1,表达式2);如果条件表达式成立,返回表达式1,否则返回表达式2.
②case
情况1
case 变量|表达式|字段
when 常量1 then 值1
when 常量2 then 值2

else 其它情况
end
情况2
case
when 条件1 then 值1
when 条件2 then 值2

else 其它情况
end

分组查询

一、分组函数

1、分组-常见的函数

max 最大值
min 最小值
sum 和
avg 平均值
count 计算个数

2、特点

①语法:
select max(字段) from 表明;
②语法:
sum和avg一般用于处理值型
max、min、count可以处理任何数据类型
③以上分组函数都忽略null
④都可以搭配distinct使用,实现去重的统计
select sum(distinct 字段) from 表;
⑤count函数
count(字段):统计该字段非空值的个数。
count():统计结果集的行数。
*案例
:查询每个部门的员工个数

  1. SELECT COUNT(*),部门 FROM 表明 FROUP BY 部门;

count(1):统计结果集的行数
效率上:
MyISAM存储引擎,count()最高
InnoDB存储引擎,count(
)和count(1)效率大于count(字段)
⑥ 和分组函数一同查询的字段,要求是group by后出现的字段。

二、语法-以及逻辑执行顺序

select 分组函数,分组后的字段 ⑤
from 表明 ①
【where 分组前条件表达式,用于筛选】 ②
group by 分组字段 ③
【having 分组后条件表达式】 ④
【order by 排序字段】 ⑥

三、特点

使用关键字 筛选的表 位置
分组前筛选 where 原始表 group by的前面
分组后筛选 having 分组后的结果 group by的后面

连接查询

一、含义

当查询中涉及到了多个表的字段
select 字段1,字段2
from 表1,表2,…
笛卡尔乘积:当查询多个表时,没有添加有效的连接条件,导致多个表所有行实现完全连接。
解决方式:添加有效的连接条件。

二、分类

按年份分类:

sql92
仅支持:内连接
内连接又分:
等值
非等值
自连接
也支持一部分外连接(用于oracel、sqlserver,mysql不支持)
sql99:【推荐使用】
支持
内连接
等值
非等值
自连接
外连接
左外
右外
全外(mysql不支持)
交叉连接

三、SQL93语法

1、等值连接

语法:
select 查询列表
from 表1 别名,表2 别名 …
where 表1.keyID = 表2.keyID
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】
特点:
① 一般的表起别名
②多表的顺序可以调换
③n表连接至少需要n-1个连接条件
④等值连接的结果是多表的交集部分

2、非等值连接

语法:
select 查询列表
from 表1 别名,表2 别名 …
where 非等值的连接条件
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】

3、自连接

语法:
select 查询列表
from 表 别名1,表 别名2 …
where 非等值的连接条件
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】

四、sql99语法

1、内连接

2、外连接

3、交叉连接

七道小题

1. 显示所有员工的姓名,部门号和部门名称
SELECT  
  e.`first_name`,
  d.`department_name`,
  d.`department_id`  
FROM
  `employees` AS e,
  `departments` AS d  
WHERE e.`department_id` = d.`department_id` ;

2. 查询90号部门员工的job_id和90号部门的location_id
SELECT  
  e.`job_id`,
  d.`location_id`,
  e.`department_id`
FROM
  `employees` AS e,
  `departments` AS d  
WHERE e.`department_id` = d.`department_id`  
  AND e.`department_id` = 90;

3.选择所有奖金的员工的 last_name,department_name,location_id,city
SELECT  
  e.last_name,
  e.`commission_pct`,
  d.department_name,
  d.location_id,
  l.city  
FROM
  `employees` AS e,
  `locations` AS l,
  `departments` AS d  
WHERE e.`commission_pct` IS NOT NULL  
  AND e.`department_id` = d.`department_id`  
  AND d.`location_id` = l.`location_id` ;

4.选择city在Toronto工作的员工的 last_name , job_id , department_id,department_name
SELECT  
  e.`last_name`,
  e.`job_id`,
  e.`department_id`,
  d.`department_name`,
  l.`city`  
FROM
  `employees` AS e,
  `departments` AS d,
  `locations` AS l  
WHERE e.`department_id` = d.`department_id`  
  AND d.`location_id` = l.`location_id`  
  AND l.`city` = 'Toronto' ;

5.查询每个工种、每个部门的部门名、工种名和最低工资
SELECT  
  d.department_name,
  j.job_title,
  MIN(e.salary) AS 最低工资  
FROM
  `departments` AS d,
  `employees` AS e,
  `jobs` AS j
WHERE d.`department_id` = e.`department_id`  
AND e.`job_id` = j.job_id  
GROUP BY d.department_name,j.job_title  
ORDER BY 最低工资 DESC;

6.查询每个国家的部门个数大于2的国家编号
SELECT  
  country_id,
  COUNT(*) 部门个数  
FROM
  departments AS d,
  locations AS l  
WHERE  
d.`location_id` = l.`location_id`
GROUP BY country_id  
HAVING 部门个数 > 2;

7.选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似于下面的格式
/*
employees    Emp#  manager  Mgr#
kochhar  101  king  100
*/
SELECT  
  e.`last_name` AS employees,
  e.employee_id AS 'Emp#' ,
  m.last_name AS manager,
  m.employee_id AS 'Mgr#'
FROM
  employees AS e,
  employees AS m  
 WHERE e.manager_id  = m.employee_id AND e.last_name = 'kochhar';