SQL笔记(入门——高级)

数据库科普:

一、数据库的好处

1.可以持久化数据到本地

2.结构化查询

二、数据库的常见概念

1.DB: 数据库,存储数据的容器

2.DBMS: 数据库管理系统,又称为数据库软件或数据库产品,用于创建或管理DB

3.SQL: 结构化查询语言,用于和数据库通信的语言,不是某个数据库软件特有的,而是几乎所有的主流数据库软件通用的语言

三、数据库存储数据的特点

1.数据存放到表中,然后表再放到库中

2.一个库中可以有多张表,每张表具有唯一的表名用来标识自己

3.表中有一个或多个列,列又称为“字段”

四、MySQL服务的启动和停止

1.通过命令行: net start 服务名      net stop 服务名

2.计算机--右击--管理--服务

五、MySQL服务的登录和退出

登录:mysql [-h 主机名 -p 端口号] -u用户名 -p 密码

退出:exit 或 ctrl+c


MySQL的常见命令:

1.查看当前所有的数据库

show databases;

2.打开指定的库

use 库名

3.查看当前库的所有表

show tables;

4.查看其他库的所有表

show tables from 库名;

5.创建表

create table 表名(

    列名 列类型,

    列名 列类型,

    。。。

);

6.查看表结构

desc 表名;

7.查看服务器的版本

(1)登录到mysql服务端:  select version();

(2)没有登录到mysql服务端

mysql --version   或    mysql --V

8.起别名

(1)使用as    : select 100%98 as 结果

(2)使用空格 : select 100%98     结果

9.mysql中的+号

仅仅只有一个功能:运算符

select 100+90;    #190        (两个操作数都为数值型,则做加法运算)

select '123'+90;   #213        (转换成功,则继续做加法运算)

select ‘john’+90;  #90          (转换失败,则将字符型数值转换成0)

select null+90;     #null        (只要一方为null,则结果肯定为null)

10.DISTINCT 去重

exp: SELECT DISTINCT job_id FROM employees;

11.模糊查询 LIKE _ %

exp1: SELECT salary FROM employees WHERE last_name LIKE '__n_l%'

exp2:查询员工名中第二个字符为_的员工名

exp2: SELECT last_name FROM employees WHERE last_name LIKE '_$_%' ESCAPE '$'  (自定义转义字符)

12.安全等于 <=> (基本不用)

既可=NULL,又可=12000  (数值)

13.排序查询 

order by 排序列表 【asc | desc】  (默认asc 升序)

14.upper、lower 大小写转换

SELECT UPPER('john');

SELECT LOWER('joHn');

exp: 将姓变大写,名变小写,然后拼接

exp: SELECT CONCAT( UPPER(last_name),LOWER(first_name) )  姓名 FROM employees;

15.substr、substring字符截取  (注:索引从1开始)

#截取从指定索引处后面所有的字符(包含)

SELECT SUBSTR('李莫愁爱上了陆展元',7)  out_put;

#截取从指定索引处后面指定字符长度的字符(包含)

SELECT SUBSTR('李莫愁爱上了陆展元',1,3)  out_put;

exp: 姓名中首字符大写,其他字符小写然后用_拼接,显示出来

exp: SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),LOWER(SUBSTR(last_name,2)))  out_put

16.instr返回子串第一次出现的索引,如果找不到返回0

SELECT INSTR('ABCDEFGHIJ','HIJ') AS out_put;

17.trim 清除两端的空格

SELECT LENGTH(TRIM('   ABC   ')) AS out_put;   # 3 

SEKECT TRIM('aa' FROM 'aaaaaaaWaaaaaaaERaaaaa') AS out_put;   # aWaaaaaaaERa

18.lpad、rpad用指定的字符实现左、右填充指定长度

SELECT LPAD('ABC',2,'@') AS out_put;  # AB

SELECT LPAD('ABC',6,'@') AS out_put;  # @@@ABC

SELECT RPAD('ABC',6,'ab') AS out_put  # ABCaba

19.replace替换

SELECT REPLACE('ABCABCWWWEEERRRABC','ABC','UP') AS out_put;  # UPUPWWWEEERRRUP

19.数学函数: round四舍五入、ceil向上取整、floor向下取整、truncate截断、mod取余

SELECT ROUND(-1.55);  # -2

SELECT ROUND(1.567,2);  # 1.57

SELECT CEIL(1.02);  # 2

SELECT FLOOR(9.99);  # 9

SELECT TRUNCATE(1.69999,1);  # 1.6

SELECT MOD(10,3);  # 1

20.时间函数: %Y %y %m %c %d %H %h %i %s

%Y  四位的年份   %y  2位的年份  %m  月份(01,02,...,11,12)  %c  月份(1,2,...,11,12) %d  日(01,02,...)

%H  小时(24小时制)  %h  小时(12小时制)  %i  分钟(00,01,...,59)   %s  秒(00,01,...,59)

21.日期函数:NOW()、CURDATE()、CURTIME()、YEAR()、MONTH()、STR_TO_DATE()、DATE_FORMAT()

SELECT NOW();           #now        返回当前系统日期+时间

SELECT CURDATE();   #curdate   返回当前系统日期,不包含时间

SELECT CURTIME();    #curtime   返回当前时间,不包含日期

#可以获取指定的部分,年,月,日,小时,分钟,秒

SELECT YEAR(NOW()) 年;

SELECT YEAR(hiredate) 年 FROM employees

SELECT MONTH(NOW()) 月;   # 数字

SELECT MONTHNAME(NOW()) 月; # 英文

#str_to_date  将字符通过指定的格式转换成日期

SELECT STR_TO_DATE('1998-3-2','%Y-%c-%d') AS out_put;

#查询入职日期为1992-4-3的员工信息

SELECT * FROM employees WHERE hiredate = '1992-4-3';

SELECT * FROM employees WHERE hiredate = STR_TO_DATE('4-3 1992','%c-%d %Y');

#date_format  将日期转换成字符

SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') AS out_put;   # 21年5月12日

#查询有奖金的员工名和入职日期(xx月/xx日  xx年)

SELECT last_name, DATE_FORMAT(hiredate,‘%m月/%d日 %y年’)入职日期

FROM employees WHERE commission_pct IS NOT NULL;

22.流程控制函数

(1)if函数: SELECT  IF(10>5,'大','小')

(2)case函数的使用一: (switch case 的效果) 

                case 要判断的字段或表达式

                when 常量1 then 要显示的值1或语句1;

                when 常量2 then 要显示的值2或语句2;

                ...

                else 要显示的值n或语句n;

                end

exp:

SELECT salary 原始工资,department_id,

CASE department_id

WHEN 30 THEN salary*1.1

WHEN 40 THEN salary*1.2

ELSE salary

END AS 新工资 

FROM employees;

(2)case函数的使用二:   (类似于  多重if)

        case

        when 条件1 then 要显示的值1或语句1;

        when 条件2 then 要显示的值2或语句2;

        ...

        else 要显示的值n或语句n

        end

exp:查询员工的工资的情况

如果工资>20000,显示A级别,如果工资>15000,显示B级别,否则,显示C级别

SELECT salary,

CASE

WHEN salary>20000 THEN 'A'

WHEN salary>15000 THEN 'B'

ELSE 'C'

END  AS 工资级别

FROM employees;

23.分组函数: sum求和、avg平均值、max最大值、min最小值、count计算个数(这5种都忽略空值)

于分组函数一同查询的字段要求是group by后的字段

24.sql99语法:

select 查询列表

from 表一 别名 【连接类型】

join 表二 别名   (inner、left、right、full、cross)

on 连接条件

【where 筛选条件】

【group by分组】

【having 筛选条件】

【order by 排序列表】

【limit  [offset , ] size】

25:子查询:出现在其他语句中的select语句

(1)按子查询出现的位置分类:

select后面: 仅仅支持标量子查询

from后面: 支持表子查询    (将子查询结果充当一张表,要求必须起别名)

where或having后面: ☆标量、列子、行子查询

exists后面:(相关子查询)表子查询

(2)按结果集的行列数不同:

标量(一行一列)、列子(一列多行)、行子(一行多列)、表子查询(多行多列)

exp1:谁的工资比Abel高?

①查询Abel的工资

SELECT salary 

FROM employees

WHERE last_name = 'Abel';

②查询员工的信息,满足salary>①的结果

SELECT *

FROM employees

WHERE salary>(

            SELECT salary 

            FROM employees

            WHERE last_name = 'Abel'

);

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

①查询每个部门的平均工资

SELECT AVG(salary),department_id

FROM employees

GROUP BY department_id

②连接①的结果集和job_grades表,筛选条件平均工资 between lowest_sal and highest_sal

SELECT avg_dep.* , g.grade_level

FROM(

            SELECT AVG(salary) avg , department_id

            FROM employees

            GROUP BY department_id

) avg_dep

INNER JOIN job_grades g

ON avg_dep.avg BETWEEN lowest_sal AND highest_sal;

exists(完整的查询语句)      # 结果:1或0

exp3:查询有员工的部门名

SELECT department_name

FROM departments d

WHERE EXISTS(

        SELECT *

        FROM employees e

        WHERE d.department_id = e.department_id

); 

或  (能有exists的绝对能用in实现)

SELECT department_name

FROM departments d

WHERE d.department_id IN(

            SELECT department_id

            FROM employees

);

26:多行子查询:IN / NOT IN、ANY|SOME、ALL

IN / NOT IN:等于列表中的任意一个

ANY|SOME:和子查询返回的某一个值比较

ALL:和子查询返回的所有值比较

27.分页查询 LIMIT   (公式: 要显示的页数page,每页条目数size    limit (page-1)*size,size ; )

exp:查询前五条员工信息

SELECT * FROM employees LIMIT 0,5;

SELECT * FROM employees LIMIT 5;

28.联合查询 UNION  将多条查询语句的结果合并成一个结果

语法: 查询语句1 union 查询语句2 union ...

应用场景:要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时

特点:☆

1.要求多条查询语句列数是一致的

2.要求多条查询语句的查询的每一列的类型和顺序最好一致

3.union关键字默认去重,如果使用union all可以包含重复项

exp:查询中国用户中男性的用户信息以及外国用户中男性的用户信息              结果# id    cname    csex

SELECT id,cname,csex FROM t_ca WHERE csex='男'                                          2        李雷        男

UNION                                                                                                                         3        李明        男

SELECT t_id,t_name,t_csex FROM t_ua WHERE t_csex='male'                           1         john      male

                                                                                                                                     4         jack      male

29.DML语言(数据操作语言)insert、update、delete

#插入语句

#插入方式一  (支持插入多行、子查询)

语法:insert into 表名(列名, ...)values(值1, ...) [,(...),(...)]  ;      # 加[ ]里的内容则为插入多行

(1)插入的值的类型要与列的类型一致或兼容

(2)不可以为null的列必须插入值,可以为null的列可插入null值或者不写

(3)列的顺序可以调换

(4)列数和值的个数必须一致

(5)可以省略列名,默认所有列,而且列的顺序和表中列的顺序一致

exp: INSERT INTO beauty VALUES( 18 , '张飞' , '男' , ‘119’ , NULL , NULL )

exp: INSERT INTO beauty(id,NAME,phone)    #插入子查询的结果集则省略values

        SELECT 26,'宋茜',‘11809866’;    

#插入方式二  (不支持插入多行、子查询)

语法:insert into 表名 set 列名=值,列名=值,...

exp: INSERT INTO beauty SET id=19,NAME='刘涛',phone='999';

#修改语句 

#修改单表的记录

语法:update 表名 set 列=新值,列=新值,...  where 筛选条件;

exp: UPDATE boys SET boyname='张飞',usercp=10 WHERE id=2;

#修改多表的记录

语法:update 表1 别名 inner|left|right join 表2 别名 on 连接条件 set 列=新值, ... where筛选条件:

exp: 修改张无忌的女朋友的手机号为114

UPDATE boys bo

INNER JOIN beauty b ON bo.id=b.boyfriend_id

SET b.phone='114'

WHERE bo.boyName='张无忌';

#删除语句

方式一:delete

语法:单表的删除:delete from 表名 where 筛选条件   

           多表的删除:delete 表1的别名,表2的别名 from 表1 别名 inner|left|right join 表2 别名 on 连接条件 where 筛选条件;

exp: 删除张无忌的女朋友的信息   (多表的删除可以删除一个表或多个表的数据,如:DELETE b,bo ... )

DELETE b 

FROM beauty b 

INNER JOIN boys bo ON b.boyfriend_id = bo.id 

WHERE bo.boyName='张无忌';

方式二:truncate 

语法: truncate table 表名;

exp: TRUNCATE TABLE boys;

dalete VS truncate

1.delete可以加where条件,truncate不能

2.truncate删除,效率高一点

3.假如要删除的表中有自增长列,如果用delete删除后,再插入数据,自增长列的值从断点开始,而用truncate则从1开始

4.truncate删除没有返回值,delete删除有返回值(执行命令时是否显示:共n行受到影响)

5.truncate删除不能回滚,delete删除可以回滚

30.DDL (数据定义语言) create、alter、drop

#库的管理

CREATE DATABASE IF NOT EXISTS books;    #创建库books

RENAME DATABASE books TO 新库名;           #修改库名

ALTER DARABASE books CHARCTER SET gbk;   #更改库的字符集

DROP DATABASE 【IF EXISTS】books;   #库的删除

#表的管理

#表的创建,语法:

create table 表名(

        列名  列的类型  【(长度)约束】,

        列名  列的类型  【(长度)约束】,

        ...

        列名  列的类型  【(长度)约束】

exp:

CREATE TABLE book(

        id INT,

        bName VARCHAR(20),

        price DOUBLE,

        authorId INT UNSIGNED,

        publishDate DATETIME

);

#表的修改

#语法:alter table 表名 add|drop|modify|change column 列名 【列类型  约束】;

ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;   #修改列名

ALTER TABLE book MODIFY COLUMN annual DOUBLE;  #修改列的类型或约束

ALTER TABLE author DROP COLUMN annual;  #删除列

ALTER TABLE author RENAME TO book_author;  #修改表名

#表的删除

DROP TABLE book_author;

#表的复制

(1)仅仅复制表的结构

CREATE TABLE copy LIKE author;

(2)复制表的结构+数据 (也可复制部分数据,如复制部分列,或者加筛选条件)

CREATE TABLE copy2

SELECT * FROM author;

(3)仅仅复制某些字段  (列名)

CREATE TABLE copy3

SELECT id,au_name

FROM author

WHERE 1=2;  (或者 WHERE 0 )

31.数值类型Tinyint、Smallint、Mediumint、Int | Interger、Bigint  (占用字节分别为:1,2,3,4,8)

数值型:整型  

              小数:定点数  浮点数

字符型:较短的文本:char、varchar

              较长的文本:text、blob(较长的二进制数据)

                其他:binary和varbinary用于保存较短的二进制

                            enum用于保存枚举

                            set用于保存集合

日期型:只保存日期 date

                只保存时间  time

                只保存年  year                          #  字节     范围             时区等的影响

                保存日期+时间  datetime              8         1000-9999    不受 

                保存日期+时间  timestamp           4         1970-2038     受

整型特点:

(1)如果不设置,默认是有符号,设置则添加unsigned关键字

(2)如果插入的数值超出了整形范围,会报out of range异常,并且插入临界值

(3)如果不设置长度,会有默认长度

小数特点:

浮点型 float(M,D)  double(M,D)        M:整数部位+小数部位

定点型 dec(M,D)  decimal(M,D)        D:小数部位

(1)如果超过范围,则插入临界值

(2)M和D都可以省略

  (如果是decimal,则M默认为10,D默认为0;如果是float和double,则会根据插入的数值的精度来决定精度)

字符型特点:

                写法           M的意思                                          特点                     空间的耗费       效率

char        char(M)       最大字符数,可以省略,默认为1    固定长度的字符   比较耗费          高

varchar   varchar(M)   最大字符数,不可以省略                可变长度的字符   比较节省          低

31.六大约束   (含义:一种限制,用于限制表中的数据,为了保证表中的数据的准确和可靠性)

NOT NULL : 非空,用于保证该字段的值不能为空

DEFAULT : 默认,用于保存该字段的默认值

PRIMARY KEY : 主键,用于保证该字段的值具有唯一性,并且非空

UNIQUE : 唯一,用于保证该字段的值具有唯一性,可以为空

CHECK : 检查约束 【mysql中不支持】

FOREIGN KEY : 外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值

                            在从表添加外键约束,用于引用主表中某列的值

添加约束的时机: 1.创建表时   2.修改表时

约束的添加分类: 1.列级约束    # 六大约束语法上都支持,但外键约束没有效果

                              2.表级约束    # 除了非空、默认,其他的都支持

                                 添加表级约束的语法: 在各个字段的最下面添加: constraint 约束名  约束类型  (字段名)

#创建表时添加约束

CREATTE TABLE 表名(

        字段名  字段类型  列级约束,

        字段名  字段类型,

        表级约束

#添加列级约束和表级约束(通用的写法)

exp:

CREATE TABLE IF NOT EXISTS stuinfo(

        id INT PRIMARY KEY,  # 主键

        stuName VARCHAR(20) NOT NULL, # 非空

        gender CHAR(1) CHECK (gender='男' OR gender='女'), # 检查

        seat INT UNIQUE, # 唯一

        age INT DEFAULT 18, # 默认约束

        majorId INT FOREIGN KEY REFERENCES major(id) # 外键


        CONSTRANT pk PRIMARY KEY(id),  # 主键

        CONSTRANT uq UNIQUE(seat),  # 唯一键  

        CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid)  REFERENCES major(id)  # 外键

);

CREATE TABLE major(

        id INT PRIMARY KEY,

        majorName VARCHAR(20)

);

SHOW INDEX FROM stuinfo;  # 查看表中的所有索引,包括主键、外键、唯一

主键 VS 唯一:

                保证唯一性   是否允许为空   一个表中可以有多少个   是否允许组合

主键                √                   ×                            至多有1个            √,但不推荐

唯一                √                    √                           可以有多个           √,但不推荐

外键:

(1)要求在从表设置外键关系

(2)从表的外键列的类型和主表的关联列的类型要求一致或兼容,名称无要求

(3)主表的关联列必须是一个key (一般是主键或唯一)

(4)插入数据时,先插入主表,再插入从表;删除数据时,先删除从表,再删除主表

#修改表时添加约束

(1)添加列级约束: alter table 表名 modify column 字段名  字段类型  新约束;

(2)添加表级约束: alter table 表名 add [constraint 约束名] 约束类型(字段名) 【外键的引用】;

CREATE TABLE stuinfo(

        id INT,

        stuname VARCHAR(20),

        gender CHAR(1),

        seat INT,

        age INT,

        majorid INT

);

ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20)  NOT NULL;  # 添加非空约束

ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18; # 添加默认约束

#添加主键

ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;  # 列级约束

ALTER TABLE stuinfo ADD PRIMARY KEY(id);  # 表级约束

#添加唯一

ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;  # 列级约束

ALTER TABLE stuinfo ADD UNIQUE(seat);  # 表级约束

#添加外键

ALTER TABLE stuinfo ADD FOREIGN KEY(majorid) REFERENCES major(id);

#修改表时删除约束

ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;  # 删除非空约束

ALTER TABLE stuinfo MODIFY COLUMN age INT;   #  删除默认约束

ALTER TABLE stuinfo DROP PRIMARY KEY;   # 删除主键

ALTER TABLE stuinfo DROP INDEX seat;   # 删除唯一  (如果不知道唯一约束名称,可以先 SHOW INDEX FROM stuinfo; )

ALTER TABLE stuinfo DROP FOREIGN KEY mojorid;   # 删除外键 (同理:可以先 SHOW INDEX FROM stuinfo; )

mysql踩坑:

1.mysql函数str_to_date(date,format)使用时报错。

排查问题,发现str_to_date(date,format)函数的第一个参数不能是空字符串,反而为null时并不影响。

解决方案:STR_TO_DATE(if(date=’’, null , date), format)

你可能感兴趣的:(SQL笔记(入门——高级))