MySQL基础-DQL

一、为什么要学习数据库

数据库的作用

  • 持久化数据到硬盘文件
  • 大量数据的的存储
  • 方便检索
  • 保证数据的一致性和完整性
  • 安全可共享
  • 通过组合分析可以产生新的数据

二、数据库的相关概念

  • DB (Data Base)数据库:存储数据的仓库,由一系列组织的数据
  • DBMS( databaseManagement System) 数据库管理系统 有组织有格式 的容器, 不是说一个大文章,使用DBMS管理和维护DB
  • SQL 结构化查询语言(Structure Query Language )结构化查询语言,程序员用于和DBMS通讯的语言储数据的特点
    数据先放在表中,表在放在数据库中
    一个库有多个表,每个表都有自己的唯一标识
    表类似于类的设计 字段类似于属性的设计 单条记录类似一个对象 所有记录类似对象的结合
    orm : object relation mapping 对象和关系的映射

三、不同数据库的产品

orcal 产品免费但是服务收费
SQLServer 不兼容 仅仅支持Winodws
而MySql

  • 体积小、安装方便
  • 开源免费- 性能高 兼容性好

DBMS分为两类:
– 基于共享文件系统的DBMS (Access )
– 基于客户机——服务器的DBMS C/S
(MySQL、Oracle、SqlServer)
MySQL数据库管理软件是C/S 结构 需要安装服务端和客户端,底层是TCP/IP协议
c :客户端
s :服务端
所以使得MySQL软件的服务器端必须先启动,客户端才可以连接和使用使用数据库。

四、

MySQL产品的安装

服务器端先启动,有一个端口号,等待客户端的连接。
–mysqld 代表的是服务端的配置
– 端口号是 3306

MySQL服务的启动和停止

  • 图形化 右击-计算机管理 - 服务-MySQL服务

  • dos

  net  start 服务名

  net  stop 服务名

MySQL服务的登录和退出

  • dos 命令
  mysql    -h主机名    -P端口号     -u 用户名    -p 密码

  注意如果是本机  -h主机名可以省略 

  如果端口是3306  -P端口号可以省略 (大写P)
  • 通过图形化界面进入

五、DQL语言的学习 ★

基础查询 ★

  select 查询列表 
  from 表名字

特点:查询的结果是一个虚拟表,查询列表是一个类似java中sout的
1.先from子句
2.select子句

  • 一、查询常量
    select 100 (from 表名字)没有也一样
    就像是sout100
  • 二、查询表达式
    select 100 %3
  • 三、查询单个字段
    着重号 ·· 就是1旁边的那个东西
  • 四、查询多个字段 或者用 * 但是语义性不强 ,就是不知道查找的是什么
    如果一行的内容太多 一般是关键字进行换行

或者是f12 快速对其格式 进行自动换行和对其的操作
五、查询函数

select database(); 查询当前所在的数据库
select version;查询版本号
select user();查询当前的用户

六、起别名

  • as 关键字
    select user() as ‘用户名’

注意常量字符加单引号 除了数值型都要加引号

  • 使用空格
    把as 替换成空格

七、查询fristname 和lastname 拼接成的全名 最终起别名尾姓名

  • :+
    select firstname + lastname
    from 表

java + 运算符是唯一一个进行重载的运算符
加法运算 100+2
2 +‘a’ = 99 或者拼接 至少有一个是字符串

mysql 中的+作用
1 加法运算 两个操作都是数值型
2 其中一个是字符型 会把字符型转换为数值型 如果无法转换就是当作0处理
两个都是字符型都是0
3 其中一个是null 都是null

所以应该使用contact

  • contact拼接字符
    如果其中一个是null最终的结果也是null

八、distinct 去重 可以用在select的选择语句里面
有可能有的部门里面没有员工, 员工的对应的的部门不一定是所有的部门

select  distinct departname from ;

九、查看表的结构

  • desc 表名字
  • show columes from 表名字

十 、ifnull

ifnull(1 ,2 )

如果表达式1为null ,显示表达式2
否则显示表达式1

如果前面是null 用后面的替换
ifnull( commision_pct,''))  

条件查询 ★

select 
from
where 条件(结果是true 或者false

执行顺序
from语句
where子句
每走完一个子句就有一个虚拟的结果

1.关系/条件表达式

、 <、 >= 、 <=、 = 、<>这是不等于(后面的这种 =不建议)

部门编号不是100
SELECT  *
FROM `employees`
WHERE `job_id`<> 100;

2.逻辑表达式

and or not (&& || ! 不建议)
mysql查询时,and or同时存在时,and的优先级高于or,必要的时候加括号

3.模糊查询

like (not like ) 、 in(not in) 、 between and(not between and)

  • like
    一般和通配符搭配,对于字符数据进行部分匹配查询
    _匹配单个字符
    % 多个字符 0-多个
姓名中既有a 又有e 
SELECT `last_name`
FROM `employees`
WHERE last_name LIKE '%a%' AND last_name LIKE '%e%';

等价于
SELECT `last_name`
FROM `employees`
WHERE last_name LIKE '%a%e%' OR last_name LIKE '%e%a%';
设置$为转移字符
ESCAPE '$';  这句话是 让$ 拥有转义字符的形式和
SELECT *
FROM `employees`
WHERE last_name LIKE '_$_%' ESCAPE '$';
  • in
    查询某字段的值是否属于指定的列表内
    IN (常量 1,2,3)
    IN (’’,’’) 非数值型的需要用单引号引用起来
    NOT IN (常量 1,2,3)
SELECT *
FROM `employees`
WHERE`job_id` NOT IN('SH_CLERK','IT_PROG');
等价于
SELECT *
FROM `employees`
WHERE  NOT (`job_id`  = 'IT_PROG'  OR 
`job_id`  = 'SH_CLERK');
  • between and
查询年薪
SELECT `last_name`,`salary`*12*(1+ IFNULL (`commission_pct` ,0)) AS '年薪'
FROM `employees`
WHERE `salary`*12*(1+ IFNULL (`commission_pct` ,0)) BETWEEN 30000 AND 100000
  • isnull 、 is not null
    注意等于判断的是空的 只能用来判断 ISNULL
SELECT *
FROM `employees`
WHERE `commission_pct` IS NULL;

排序查询 ★

语法

SELECT
FROM
WHERE 条件
ORDER BY 排序列表 可以多个

执行顺序
FROM
WHERE
SELECT
ORDER BY 先查出来之后,在进行排序 特点
排序列表可以是单个字段、多个字段、表达式、函数、列数、别名以及以上的组合
升序 ASC – ascend 降序 DESC – descend
SELECT 中的项目不必出现在ORDER BY中)—不建议使用!

由于order by是在select之后的,所以可以堆别名进行排序。

按别名排序
(排序可以别名 WHERE 不可以别名的原因就是语句的顺序不一样)
SELECT *,`salary`*(1 + `commission_pct`)*12 年薪
FROM `employees`
WHERE  `commission_pct` IS NOT NULL
ORDER BY 年薪 DESC 
查询邮箱中包含e的员工信息,并按照邮箱的字节数降序,再按照部门号升序
SELECT *
FROM `employees`
WHERE `email`LIKE '%e%'
ORDER BY LENGTH(`email`)DESC ,`manager_id`ASC;

常见函数 ★

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

单行函数

1、字符函数
concat:连接
substr:截取子串 截取字符串 SQL的起始所索引是1开始
upper:变大写
lower:变小写
replace:替换
length:获取字节长度
trim:去前后空格
lpad:左填充
rpad:右填充
instr:获取子串第一次出现的索引

示例:

CONCAT ()拼接字符
LENGTH  () 获取字节长度  utf-8 一个汉字是三个字节
	 SELECT LENGTH('hello,') // 6
	 SELECT LENGTH('hello,') // 8
	 SELECT LENGTH('hello,解淇茹') // 15 6 + 3*3
CHAR LENGTH() 获取字符个数
	SELECT  CHAR_LENGTH('hello,解淇茹') //9	
SUBSTRING 截取字符串 SQL的起始所索引是1开始
	  SUBSTR(起始的索引,截取字符长度)
	  SUBSTR(起始的索引) 默认到结束
INSTR 获取字符第一次出现的索引
TRIM 去除前后指定的字符,默认是去除空格
	 SELECT TRIM('     1 2 3    ')
	 SELECT TRIM( 'x' FROM 'xxxx 1x2x3 xxxxx') 指定去除的是x
LPAD RPAD 左填充 /右填充
	SELECT LPAD('xqr',10,6);//一共填充为10个字符用6左填充如果数字小于未进行填充前的,就不填充了
UPPER/LOWER
STRCMP 比较两个字符的大小
	 先比较第一个一样再继续,不一样就不比较了
LEFT/RIGHT 截取子串
	SELECT LEFT('xqr',1)
	SELECT RIGHT('xqr',1)
 
2、数学函数
ceil:向上取整
round:四舍五入
mod:取模
floor:向下取整
truncate:截断
rand:获取随机数,返回0-1之间的小数
ASC 绝对值
CEIL 向上取整,返回》= 参数的最小整数
FLOOR 向下取整 返回 《= 参数的最大整数
ROUND 四舍五入
	 SELECT ROUND(-2,4) //-2
	 SELECT ROUND(-2.5) // -3 注意这个
	 SELECT ROUND(-2.6)
TRUNCATE 截断
MOD 取余
	 a%b = a-a/b*b
	 余数是和被除数的符号相同
	 SELECT MOD(-10,3)//-1
	 SELECT MOD(10,-3) // 1
3、日期函数
now:返回当前日期+时间
year:返回年
month:返回月
day:返回日
date_format:将日期转换成字符
curdate:返回当前日期
str_to_date:将字符转换成日期
curtime:返回当前时间
hour:小时
minute:分钟
second:秒
datediff:返回两个日期相差的天数
monthname:以英文形式返回月

在这里插入图片描述

4、其他函数
version 当前数据库服务器的版本
database 当前打开的数据库
user当前用户
password('字符'):返回该字符的密码形式
md5('字符'):返回该字符的md5加密形式
5、流程控制函数
if(条件表达式,表达式1,表达式2):
如果条件表达式成立,返回表达式1,否则返回表达式2
case的两种用法
case情况1
相当于Java的switch
case 变量或表达式或字段
when 常量1 then 值1
when 常量2 then 值2
...
else 值n
end

case情况2
相当于Java的if...else if...
case 
when 条件1 then 值1
when 条件2 then 值2
...
else 值n
end       

分组函数 ★

语法

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

特点

分组函数往往将一组数据进行统计计数,最终的到一个值。聚合函数是用来做纵向运算的函数:

SUM(字段名) 求和
AVG(字段名)平均数
MAX(字段名)最大值
MIN(字段名)最小值
COUNT(字段名)计算非空字段值的个数
max min count 可以用于字符型计算 sum 和avg只能数值类型

MAX()、MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
SUM()、AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;

示例:

COUNT 重点说 计算非空的个数 
所有函数的使用注意就是函数名()()之间不能有空格
1.计算表的行数 COUNT (*)
SELECT COUNT(*) FROM `employees`;
SELECT COUNT(*) FROM `employees` WHERE `department_id` = 30;
2.count (1) -- 补充了解
相当于是在你的表中加入了一个常量列 里面都是1
所有统计的就是一共在多少行里面加了1
SELECT COUNT(1) FROM `employees`;
SELECT COUNT(1) FROM `employees` WHERE `department_id` = 30;
3.搭配DISTINCT 去重
求有员工的部门个数
先把员工表里面的所有部门列出来,然后去重然后统计个数
注意DISTINCT 是关键字不是函数
SELECT COUNT(DISTINCT `department_id`)FROM `employees`;

分组查询 ★

语法

SELECT
FROM
WHERE 
GROUP BY 分组列表 (可以是一个或者多个)
HAVING 分组后筛选(==having 后面可以有聚合函数的别名,虽然having的执行顺序确实是在select之后的==ORDER BY 排序列表

注意如果select 的字段没有在group by中出现,这样的sql语句是无效的

执行顺序
FROM
WHERE
GROUP BY
HAVING
SELECT
ORDER BY

特点:
在这里插入图片描述

每个部门的总工资和平均工资
SELECT  `department_id`,SUM(`salary`),AVG(`salary`)
FROM`employees`
GROUP BY`department_id`;


-- 注意下面的如果select 的字段没有在group by中出现
-- 这样的sql语句是无效的
-- 显示出来的id是第一个的
SELECT  `department_id`,SUM(`salary`),AVG(`salary`),`employee_id`
FROM`employees`
GROUP BY`department_id`;

#2 having  分组后的筛选
执行顺序是在GROUP BY的后面

虽然HAVING是 在SELECT之后的但是HAVING 可以用SELECT的别名

查询那个部门的员工数 >5
SELECT  COUNT(*)AS 员工个数,`department_id`
FROM `employees`
GROUP BY `department_id`
HAVING  COUNT(*) >5;


高进阶
SELECT `job_id`,MAX(`salary`) AS '最高工资'
FROM`employees`
WHERE
`commission_pct` IS NOT NULL
GROUP BY `job_id`
HAVING  MAX(`salary`) > 6000
ORDER BY  MAX(`salary`) ASC;# order by在select之后

连接查询 ★

当查询中涉及到了多个表的字段,需要使用多表连接 (至少一张表)

分类

按年代分类:

sql92:mysql仅仅支持内连接 > 也支持一部分外连接(用于oracle、sqlserver,mysql不支持)

内连接包括如下

  • 等值
  • 非等值
  • 自连接

sql99【推荐使用】

  • 内连接 等值 非等值 自连接
  • 外连接 左外 右外 全外(mysql不支持)
  • 交叉连接
SQL92语法

1、等值连接

语法:
	select 查询列表
	from1 别名,2 别名
	where1.key=2.keyand 筛选条件】
	【group by 分组字段】
	【having 分组后的筛选】
	【order by 排序字段】

特点:
① 一般为表起别名
②多表的顺序可以调换
③n表连接至少需要n-1个连接条件
④等值连接的结果是多表的交集部分

2、非等值连接

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

3、自连接
也就是相同的表进行连接

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

1、内连接

分类: 等值连接 非等值连接 自连接

语法:
select 查询列表
from1 别名
【innerjoin2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;

特点:
①表的顺序可以调换
②内连接的结果=多表的交集
③n表连接至少需要n-1个连接条件

和sql 92 的语法区别就是要 表的连接方式(join)以及连接条件在on后面

2、外连接
外连接和内连接的区别
内连接选择的是一张表有,另一张表也有的 (相当于交集)
而外连接一张表有,另一张表没有(一张表是主表,另一张表是从表)。外连接可以做到将主表里面的每一天数据记录都显示出来,从表没有的就是null

语法:
select 查询列表
from1 别名
left|right|fullouterjoin2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;

特点:
①查询的结果=主表中所有的行,如果从表和它匹配的将显示匹配行,如果从表没有匹配的则显示null
②left join 左边的就是主表,right join 右边的就是主表
full join 两边都是主表
③一般用于查询除了交集部分的剩余的不匹配的行

INNER JOIN 两边表同时有对应的数据,即任何一边缺失数据就不显示。
LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据。 RIGHT JOIN 会读取右边数据表的全部数据,即便左边表无对应数据

3、交叉连接
(不常用)

语法:
select 查询列表
from1 别名
cross join2 别名;

特点:
类似于笛卡尔乘积

4.全外连接
是在结果中除了显示满足连接的条件的行外,还显示了join两侧表中所有满足检索条件的行

总结连接查询

sql92 和sql99,有一个显而易见的SQL优化的方案是,当两张表的数据量比较大,又需要连接查询时,
应该使用 FROM table1 JOIN table2 ON xxx的语法,
避免使用 FROM table1,table2 WHERE xxx 的语法,
因为后者会在内存中先生成一张数据量比较大的笛卡尔积表,增加了内存的开销。

在这里插入图片描述
下面的情况暂时不支持
在这里插入图片描述

子查询

嵌套在其他语句内部的select语句称为子查询或内查询,外面的语句可以是insert、update、delete、select等,一般select作为外面语句较多外面如果为select语句,则此语句称为外查询或主查询。

特点

  1. 子查询放在小括号内
  2. 子查询一般放在条件的右侧
  3. 标量子查询一般搭配单行操作符使用 (就是大于等于 小于 不等于之类的)
  4. 列子查询一般搭配多行操作符使用 in, any/some, all

< any 等价于 < max 比任意一个低,就做到比最大的低就可以了
< all < min

  1. 子查询的执行优先主查询
  2. 分类

1、按出现位置

  • select后面: 仅仅支持标量子查询
  • from后面: 表子查询
  • where或having后面: 标量子查询 列子查询 行子查询
  • exists后面: 标量子查询 列子查询 行子查询

2、按结果集的行列

  • 标量子查询(单行子查询):结果集为一行一列
  • 列子查询(多行子查询):结果集为多行一列
  • 行子查询:结果集为多行多列
  • 表子查询:结果集为多行多列
在where或having后

1、标量子查询


案例:查询最低工资的员工姓名和工资
①最低工资
select min(salary) from employees

②查询员工的姓名和工资,要求工资=select last_name,salary
from employees
where salary=(
	select min(salary) from employees
);


2、列子查询
在这里插入图片描述


案例:查询所有是领导的员工姓名
①查询所有员工的 manager_id
select manager_id
from employees

②查询姓名,employee_id属于①列表的一个
select last_name
from employees
where employee_id in(
	select manager_id
	from employees
);
select后面
1:查询每个部门的员工个数

SELECT d.*,(
	SELECT COUNT(*)
	FROM employees e
	WHERE e.department_id=d.department_id
) 个数
FROM departments d;
2:查询员工号为102的部门名

SELECT (
	SELECT department_name
	FROM departments
	INNER JOIN employees e
	ON d.department_id=e.department_id
	WHERE e.employee_id=102
) 部门名;
from后面

查询结果充当一张表,必须起别名

例:查询每个部门的平均工资的工资等级

//(1)查询每个部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id

//(2)连接(1)的结果集和job_grades表,筛选条件平均工资between lowest and highest
SELECT avg_dep.*g,grade_level,
FROM (
	SELECT AVG(salary) avg_sal,department_id
	FROM employees
	GROUP BY department_id
) avg_dep
INNER JOIN job_grade g
ON avg_dep.avg_sal BETWEEN g.lowest_sal AND g.highest_sal;
exists后面(相关子查询)

语法
exists(完整的查询语句)
结果:1/0

1:查询有员工的部门名

SELECT department_name
FROM departments d
WHERE EXISTS(
	SELECT *
	FROM employees e
	WHERE e.department_id=d.department_id
);
//可以用IN的方式代替
SELECT department_name
FROM departments d
WHERE d.department_id IN(
	SELECT department_id
	FROM employees
)

分页查询

应用场景

当要查询的条目数太多,一页显示不全
web页面跳转,页面上的数据一页显示不全,需要分页显示
分页查询上的sql命令请求数据库服务器,服务器响应查询到的多条数据到前端页面

语法-- 自此可以列出所有语句的执行顺序问题
特别注意的就是先select 之后才order by 和limit

select 查询列表 ⑦
from 表  ①
joinonwheregroup byhavingorder bylimitoffset】size;

注意: offset代表的是起始的条目索引,默认从0
size代表的是显示的条目数

公式:

假如要显示的页数为page,每一页条目数为size

pagesize
1limit0,10
2limit 10,10
3limit 20,10

select 查询列表
from 表
limit (page-1)*size,size;

union联合查询

要查询的结果来自于多个表且多个表没有直接的连接关系,这个时候使用联合查询。和连接查询的区别就是,连接的两个表是由可以连接的关系的。

语法

select 查询列表 
fromunion

select 查询列表 
fromunion

特点
union:合并、联合,将多次查询结果合并成一个结果

1、要求多条查询语句的查询列数必须一致
2、要求多条查询语句的查询的各列类型、顺序最好一致
3、union 去重,union all包含重复项

例:查询中国用户中男性的信息以及外国用户中男性的信息

SELECT id,cName,cSex FROM t_ca WHERE cSex='男'
UNION
SELECT t_id,tName,tGender FROM t_ua WHERE tGender='male'; 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值