SQL 语言之一:DQL 语言
DQL ,Data Query Language,数据查询语言。
一、基础查询
select 查询列表 from 表名;
- SQL 语句都以英文分号 或者 \g 结尾。
- SQL 语句不区分大小写,但推荐关键字大写:SELECT、FROM、AS、DISTINCT、LIKE、BETWEEN AND、IN、IS NULL、WHERE、ORDER BY、GROUP BY 、INSERT INTO、DELETE、UPDATE等。(不过为了能更快明白 SQL 语句,下面还是用小写字母做示例)
- 查询列表可以是单个字段、多个字段、所有字段、常量值、表达式、函数、别名、
select 某字段名 from 表名; #查询列表是单个字段
select 字段名1,字段名2,…… from 表名; #查询列表是多个字段
select 字段名1,字段名2,……,字段名n from 表名; # 查询列表是所有字段①
select * from 表名; #查询列表是所有字段②,用*号查询出的所有字段排列顺序是固定的。
select 'Moonlight'; #查询列表是常量值①
select 100; #查询列表是常量值②
select 100%30; #查询列表是表达式
select 函数名(参数列表); #查询列表是函数,比如 select VERSION();
select 字段1 as 别名1,字段2 as 别名2 from 表名; #查询列表是字段的别名
- SQL 查询语句中如何去重?使用 distinct 关键字,放在被查询的单个字段前面:
select distinct 字段名 from 表名;
- SQL 语句中的 + 号,跟 Java 语言不同,这里的 + 号只做运算符使用:
select 90+100; #两个操作数都为数值型,则做加法运算;
select '123'+90; #只有其中一方为字符型,才试图将字符型数值转换成数值型;如果转换成功,则继续做加法运算;
select 'John'+90; #只有其中一方为字符型,才试图将字符型数值转换成数值型;如果转换失败,则将字符型数值转换成0,再做加法运算;
select null+90;#只有其中一方为null,则结果肯定为null。
#【!!!】mysql中的连接使用的是CONCAT(字段名1,字段名2,……,字段名n)
二、条件查询
select 查询列表 from 表名 where 筛选条件;
2.1、 筛选条件:条件表达式。条件运算符有
> #大于
< #小于
= #等于
>= #大于等于
<= #小于等于
<> #不等于
2.2、 筛选条件:逻辑表达式。逻辑运算符有
and #与,同 Java 中的 &&
or #或,同 Java 中的 ||
not # 非,同 Java 中的 !
2.3、 筛选条件:模糊查询
a. like
#like 一般和通配符一起使用,通配符有
#%(百分号),匹配任意多个字符,包含0个字符
#_(下划线),匹配单个字符
#查询姓名为‘王’的学生信息
select * from student where stuname like '王%';
#查询姓名第二个字是‘一’的学生信息
select * from student where stuname like '_一%';
b. between and
#between 条件1 and 条件2 ,包含条件值,且两条件颠倒顺序后查询无结果(in类似于条件运算的 >= 和 <= )
#查询语文成绩在90到100之间的学生信息。
select * from student where chinese between 90 and 100;
c. in
#in(字段名1,字段名2,……,字段名n) ,in列表的值类型必须一致或者兼容,且括号中不支持使用通配符(in类似于条件运算符=)
#查询姓名为“王二”和“李一”的学生信息。
select * from student where stuname in('王二','李一');
d. is null
#sql语言中的条件运算符=、<>不能判断值是否为null,判null值只能用 is null 或者 is not null ,或者安全等于<=>
#查询语文考试没有来的学生信息,没来考试的学生成绩为NULL。
select * from student where chinese is null;
三、排序查询
select 查询列表 from 表名
【where 条件】
order by 排序列表 【asc | desc】
/*
asc是升序,没有明确说明升降序时默认升序。desc降序。
排序列表,支持
-字段名、
-表达式、
-别名、
-函数(如求字符长度的函数LENGTH(字段) )、
-多个字段(…… order by 字段名1 desc, 字段名2 asc, ……; )
*/
菜鸟教程 :MySQL 排序
四、MySQL函数
MySQL 函数分了两大类:单行函数和分组函数,单行函数又包括字符函数、数字函数、日期函数、其他函数、流程控制函数。
4.1、字符函数
LOWER(s)、UPPER(s)、CONCAT(s1, s2, ……)、SUBSTR(s, start, length)、LENGTH(s)、INSTR(s, 子串)、LPAD(s1,len,s2)、RPAD(s1,len,s2)、TRIM(s)、REPLACE(str, from_str, to_str)
LOWER(s) #将字符串 s 的所有字母变成小写字母
UPPER(s) #将字符串转换为大写
CONCAT(s1, s2, ……) #字符串 s1,s2 等多个字符串合并为一个字符串
SUBSTR(s, start, length) #从字符串 s 的 start 位置截取长度为 length 的子字符串
LENGTH(s) #获取参数值的字节个数
INSTR(s, 子串) #返回子串在 s 第一次出现的索引值,如果找不到返回0
LPAD(s1,len,s2) #在字符串 s1 的开始处填充字符串 s2,使字符串长度达到 len
RPAD(s1,len,s2) #在字符串 s1 的结尾处添加字符串 s2,使字符串的长度达到 len
TRIM(s) #去掉字符串 s 开始和结尾处的空格
REPLACE(s, from_str, to_str) #将字符串 to_str 替代字符串 s 中的字符串 from_str
4.2、数字函数
ROUND(x)、CEIL(x)、FLOOR(x)、TRUNCATE(x,y)、MOD(x,y)
ROUND(x) #返回离 x 最近的整数
CEIL(x) #返回大于或等于 x 的最小整数
FLOOR(x) #返回小于或等于 x 的最大整数
TRUNCATE(x,y) #返回数值 x 保留到小数点后 y 位的值(与 ROUND 最大的区别是不会进行四舍五入)
MOD(x,y) #返回 x 除以 y 以后的余数
4.3、日期函数
NOW()、CURDATE()、CURTIME()、STR_TO_DATE(string, format_mask) 、DATE_FORMAT(d,f) 、【YEAR(d)、MONTH(d)、DAY(d)、HOUR(t) 、MINUTE(t) 、SECOND(t)】
4.4、 其他函数
VERSION() 、DATABASE() 、USER() 、【PASSWORD(s)、MD5(s)】
select VERSION();#返回数据库的版本号。
select DATABASE();#返回当前数据库名。
select USER();#返回当前用户的用户名。
select PASSWORD(s);#返回该字符s的密码形式结果。
select MD5(s);#返回该字符s的md5加密形式结果。
4.5、流程控制函数
if 函数:if(expr1, v1, v2)、case 函数
#case 函数1:类似 Java 中的 switch case 函数
CASE 要判断的字段或表达式
WHEN 常量1 THEN 要显示的值1或语句1
WHEN 常量2 THEN 要显示的值2或语句2
……
ELSE 要显示的值n或语句n
END
#case 函数2:类似 Java 中的多重判断
CASE
WHEN 条件1 THEN 要显示的值1或语句1
WHEN 条件2 THEN 要显示的值2或语句2
……
ELSE要显示的值n或语句n
END
4.6、 分组函数
SUM(expression) 、AVG(expression) 、MAX(expression) 、MIN(expression) 、COUNT(expression)
SUM(expression) #返回指定字段的总和
AVG(expression) #返回一个表达式的平均值,expression 是一个字段
MAX(expression) #返回字段 expression 中的最大值
MIN(expression) #返回字段 expression 中的最小值
COUNT(expression) #返回查询的记录总数,expression 参数是一个字段或者 * 号
菜鸟教程 :MySQL 函数
五、分组查询
select 分组函数, 列(要求此列出现在 group by 的后面)
from 表名
【where 筛选条件】
group by 分组的列表
【order by 子句】
菜鸟教程 :MySQL GROUP BY 语句
六、连接查询
-
sql92标准,仅支持内连接,即等值连接、非等值连接、自连接
select 查询列表 from 表1 别名1,表2 别名2 where 连接条件
-
sql99标准,支持内连接,左外、右外连接,交叉连接
select 查询列表 from 表1 别名 【连接类型】join 表2 别名 on 连接条件 【where 筛选条件】 【group by 分组子句】 【having 筛选条件】 【order by 排序列表】 /* 连接类型 -内连接:inner -外连接 左外:left【outer】 右外:right【outer】 */
连接查询总结:
1、内连接结果是多表的交集部分。
2、外连接查询结果 = 内连接结果 + 主表有而从表中没有的记录。
2.1、外连接的查询结果为主表中的所有记录:如果从表中有和它匹配的,则显示匹配的值;如果从表中没有和它匹配的,则显示 NULL 。
2.2、left join 左边的是主表,right join 右边的是主表。
2.3、左外和右外交换两个表的顺序,可以实现同样的效果。
2.4、全外连接 = 内连接结果 + 表1中有但表2中没有的 + 表2中有但表1中没有的。
3、交叉连接结果是一个笛卡尔乘积。
菜鸟教程:MySQL 连接的使用
七、子查询
子查询又称为内查询,是指出现在其他语句(增删改查)中的 select 语句。内部嵌套其他 select 语句的查询,称为主查询或外查询。
- 子查询放在小括号内,且语句末尾不用加分号结尾。
- 子查询一般放在条件的右侧。
- 标量子查询,一般搭配着单行操作符使用(>、<、>=、<=、<>);列子查询,一般搭配着多行操作符使用(in、any/some、all)。
- 子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果。
按子查询出现的位置可以分为以下四大类:
select 后面的子查询(select 后面仅支持标量子查询)、
from 后面的子查询(from 后面支持表子查询)、
where 或 having 后面的子查询(where 或 having 后面支持标量子查询、列子查询和行子查询)、
exists 后面的子查询(又称为相关子查询)(exists 后面支持表子查询)
按子查询的结果集可以分为以下四类:
标量子查询(结果集只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集只有一行多列)
表子查询(结果集一般为多行多列)
#where 或 having 后面支持的标量子查询
#案例:返回公司工资最少的员工的last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
SELECT MIN(salary)
FROM employees
);
#where 或 having 后面支持的列子查询
#案例:返回location_id是1400或1700的部门中的所有员工姓名last_name(部门编号department_id)
SELECT last_name
FROM employees
WHERE department_id <>ALL(
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
);
八、分页查询
select 查询列表
from 表
【join type join 表2 on 连接条件】
【where 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序的字段】
limit 【offset, 】size;
#offset:要显示条目的起始索引,注意**索引从0开始**。
#size:要显示的条目个数。
分页公式:假设要显示的页数page,要显示的条目数size,语法如下:
select 查询列表
from 表
limit (page-1)*size,size
九、union 联合查询
union,联合,合并。在 SQL 语句中表示将多条查询语句的结果合并成一个结果。当要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时使用 union 联合查询。
查询语句1
union
查询语句2
union
……
查询语句n;
- 要求多条查询语句的查询列数是一致的;
- 要求多条查询语句查询的每一列的顺序和类型最好一致;
- union 关键字默认去重,与之相反的 union all 可以包含重复项。