一、MySQL安裝與配置
1、MySQL簡介
why
數據在內存中容易丟失
數據在文件中,不便于操作
what
使用完整的管理系統統一管理,易于查詢
where
凡是需要持久化存儲數據的地方
木語
DB
數據庫(database):存儲數據的“倉庫”。它保存了一系列有組織的數據。
DBMS
數據庫管理系統(Database Management System)。數據庫是通過DBMS創建和操作的內器
SQL
結構化查詢語言(Structure Query Language):專門用來與數據庫通信的語言
2、MySQL安裝(linux版)
#刪除系統中的mariadb rpm包
rpm -e --nodeps `rpm -qa|grep -i mariadb`
#創建MySQL所用的用戶和組
groupadd -r mysql && useradd -r -g mysql -s /bin/false -M mysql
#創建存儲文件夾
mkdir /data
#解壓壓縮包
tar zxf mysql.8.0.22.tar.gz
#編寫配置文件(my.cnf)
vim /etc/my.cnf
[mysqld]
# 不區分大小寫
lower_case_table_names=1
#設置分頁內存和超時
max_allowed_packet=100000000
.NET_buffer_length=100000
interactive_timeout=28800000
wAIt_timeout=28800000
#sqlmodel
sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
# 設置3306端口
port=3306
# 設置mysql的安裝目錄
basedir=/data/mysql
# 設置mysql數據庫的數據的存放目錄
datadir=/data/mysql/data
# 允許最大連接數
max_connections=200
# 允許連接失敗的次數。
max_connect_errors=10
# 服務端使用的字符集默認為utf8mb4
character-set-server=utf8mb4
# 創建新表時將使用的默認存儲引擎
default-storage-engine=INNODB
# 默認使用“mysql_native_password”插件認證
#mysql_native_password
default_authentication_plugin=mysql_native_password
[mysql]
# 設置mysql客戶端默認字符集
default-character-set=utf8mb4
[client]
#設置mysql客戶端連接服務端時默認使用的端口
port=3306
#初始化數據庫(無密碼初始化)
bin/mysqld --defaults-file=/etc/my.cnf --user=mysql --initialize-insecure
#結果:
2023-08-14T08:06:03.639569Z 0 [Warning] [MY-010915] [Server] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
2023-08-14T08:06:03.639705Z 0 [System] [MY-013169] [Server] /data/mysql/bin/mysqld (mysqld 8.0.22) initializing of server in progress as process 4176
2023-08-14T08:06:03.683673Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2023-08-14T08:06:04.515375Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2023-08-14T08:06:05.772764Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
#啟動數據庫
support-files/mysql.server start
#停止數據庫
support-files/mysql.server stop
#重啟數據庫
support-files/mysql.server restart
#查看端口
ss -anpt | grep 3306
3、mysql默認數據庫里面的四張表(user,db,tables_priv,columns_priv)
1、user表(用戶層權限)
因為字段太多,只截取了一部分。首先登陸的時候驗證Host,User,Password(authentication_string)也就是ip,用戶名,密碼是否匹配,匹配登陸成功將會為登錄者分配權限,分配權限的順序也是按照上面四張表的排列順序進行的,舉個例子,如果user表的Select_priv為Y說明他擁有所有表的查找權限,如果為N就需要到下一級db表中進行權限分配了。其中的%是通配符,代表任意的意思。
2、db表(數據庫層權限)
來到db表之后會匹配Host,User然后會根據Db字段對應的表進行權限分配,像Select_priv這些字段對應的權限大家應該都能看出來是對應著什么權限了吧,這里不細說了(不偷懶,舉個例子Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv分別代表著查詢,增加,更新,刪除,創建,銷毀)。其中Y代表著擁有此項權限,N則代表沒有此項權限。
3、tables_priv表(表層權限)
與上面一樣,這是通過Host,Db,User,Table來進行定位到表層的一個權限分配。不過它只有Table_priv和Column_priv兩個字段來記錄權限。
4、columns_priv表(字段層權限)
顧名思義,字段層權限,通過Host,Db,User,Table,Column來進行定位到字段層的一個權限分配,只有Column_priv來記錄權限。
相關SQL
SELECT Host,User,authentication_string from user;
SELECT * from user;
SELECT * from db;
SELECT * from tables_priv;
SELECT * from columns_priv;
二、mysql之賬號管理、建庫以及四大引擎
賬號管理一定是從mysql庫開始的
use mysql
1、數據庫賬號及權限管理
1.查詢用戶
SELECT * FROM user;
2.創建用戶并設置登錄密碼(MySQL5.7)
#命令:
create user 用戶名 identified by '密碼';
#注:
identified by會將純文本密碼加密作為散列值存儲
create user ls identified by '123456';
MySQL8
#用戶名密碼創建需要分開
#命令:
create user 用戶名;
create user ls;
3.查看用戶信息(MySQL5.7)
select host,user,password from user;
MySQL8
select host,user,authentication_string from user;
4.刪除用戶(慎用)
命令:drop user 用戶名:drop user ls;
5.修改用戶密碼
5.1修改密碼(MySQL5.7)
命令:
set password for 用戶名=password('新密碼');
set password for zs=password('123456');
MySQL(8)
ALTER USER 用戶 IDENTIFIED WITH mysql_native_password BY '密碼';
ALTER USER 'ls'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
5.2刷新配置
命令:flush privileges;
MySQL5.7與MySQL8關于權限操作沒有差異性
6.設置權限(Grant)
#語法:grant privileges on databasename.tablename to username@'host';
#給 zs用戶 賦予 數據庫db_xiaoli中的表t_p1_user 查詢權限
grant SELECT on db_xiaoli.t_p1_user to zs@'%';
#給 zs用戶 賦予 數據庫db_xiaoli中的表t_p1_user 修改權限
grant UPDATE on db_xiaoli.t_p1_user to zs@'%';
#給 zs用戶 賦予 數據庫db_xiaoli中所有表 查詢權限
grant SELECT on db_xiaoli.* to zs@'%';
#給 zs用戶 賦予 數據庫db_xiaoli中所有表 所有權限
grant ALL on db_xiaoli.* to zs@'%';
7.撤銷權限(Revoke)
#語法:revoke privileges on databasename.tablename from username@'host';
#啥也不能回收,不會對GRANT ALL PRIVILEGES ON `db_xiaoli`.* TO `zs`@`%`有任何影響
revoke DELETE on db_xiaoli.t_p1_user from zs@'%';
#可以回收GRANT SELECT, UPDATE ON `db_xiaoli`.`t_p1_user` TO `zs`@`%`這條權限語句
revoke all on db_xiaoli.t_p1_user from zs@'%';
#可以回收GRANT ALL PRIVILEGES ON `db_xiaoli`.* TO `zs`@`%`這條賦權語句帶來的權限
revoke all on db_xiaoli.* from zs@'%';
#注:revoke只能回收grants列表中更小的權限;
設置權限(Grant)和撤銷權限(Revoke)的參數說明:
1) privileges:用戶的操作權限,如SELECT,INSERT,UPDATE,DELETE等,如果要授予所有權限直接使用:all;
2) databasename:數據庫名;
3) tablename: 表名,如果要授予用戶對所有數據庫和表的操作權限直接使用:*.*;
8.查看用戶權限
命令:
show grants for 用戶名
show grants for 'zs'@'%';
user表中host列的值的意義
% 匹配所有主機
localhost localhost不會被解析成IP地址,直接通過UNIXsocket連接
127.0.0.1 會通過TCP/IP協議連接,并且只能在本機訪問;
::1 ::1就是兼容支持ipv6的,表示同ipv4的127.0.0.1
2、數據庫創建
1.MySQL默認數據庫介紹
1)information_schema:是一個信息數據庫,它保存著關于MySQL服務器所維護的所有其他數據庫的信息;
2)mysql:核心數據庫,類似于sql server中的master表,主要負責存儲數據庫的用戶、權限設置、關鍵字等mysql自己需要使用的控制和管理信息;
3)test:測試數據庫,沒有東西;
2.創建數據庫
語法:create database 數據庫名;
或者
create database if not exists 數據庫名 default charset utf8 collate utf8_general_ci;
注:默認的數據庫編碼集:utf8(即UTF-8),collate表示排序規則為utf8_general_ci
3.查看所有數據庫
語法:show databases;
4.刪除數據庫(慎用)
語法:drop database 數據庫名;
3、四大引擎的作用和區別
存儲引擎查看
MySQL給開發者提供了查詢存儲引擎的功能,我這里使用的是MySQL5.1,可以使用:
SHOW ENGINES
InnoDB存儲引擎
InnoDB是事務型數據庫的首選引擎,支持事務安全表(ACID),支持行鎖定和外鍵,上圖也看到了,InnoDB是默認的MySQL引擎。InnoDB主要特性有:
1、InnoDB給MySQL提供了具有提交、回滾和崩潰恢復能力的事物安全(ACID兼容)存儲引擎。InnoDB鎖定在行級并且也在SELECT語句中提供一個類似Oracle的非鎖定讀。這些功能增加了多用戶部署和性能。在SQL查詢中,可以自由地將InnoDB類型的表和其他MySQL的表類型混合起來,甚至在同一個查詢中也可以混合
2、InnoDB是為處理巨大數據量的最大性能設計。它的CPU效率可能是任何其他基于磁盤的關系型數據庫引擎所不能匹敵的
3、InnoDB存儲引擎完全與MySQL服務器整合,InnoDB存儲引擎為在主內存中緩存數據和索引而維持它自己的緩沖池。InnoDB將它的表和索引在一個邏輯表空間中,表空間可以包含數個文件(或原始磁盤文件)。這與MyISAM表不同,比如在MyISAM表中每個表被存放在分離的文件中。InnoDB表可以是任何尺寸,即使在文件尺寸被限制為2GB的操作系統上
4、InnoDB支持外鍵完整性約束,存儲表中的數據時,每張表的存儲都按主鍵順序存放,如果沒有顯示在表定義時指定主鍵,InnoDB會為每一行生成一個6字節的ROWID,并以此作為主鍵
5、InnoDB被用在眾多需要高性能的大型數據庫站點上
InnoDB不創建目錄,使用InnoDB時,MySQL將在MySQL數據目錄下創建一個名為ibdata1的10MB大小的自動擴展數據文件,以及兩個名為ib_logfile0和ib_logfile1的5MB大小的日志文件
MyISAM存儲引擎
MyISAM基于ISAM存儲引擎,并對其進行擴展。它是在Web、數據倉儲和其他應用環境下最常使用的存儲引擎之一。MyISAM擁有較高的插入、查詢速度,但不支持事物。MyISAM主要特性有:
1、大文件(達到63位文件長度)在支持大文件的文件系統和操作系統上被支持
2、當把刪除和更新及插入操作混合使用的時候,動態尺寸的行產生更少碎片。這要通過合并相鄰被刪除的塊,以及若下一個塊被刪除,就擴展到下一塊自動完成
3、每個MyISAM表最大索引數是64,這可以通過重新編譯來改變。每個索引最大的列數是16
4、最大的鍵長度是1000字節,這也可以通過編譯來改變,對于鍵長度超過250字節的情況,一個超過1024字節的鍵將被用上
5、BLOB和TEXT列可以被索引
6、NULL被允許在索引的列中,這個值占每個鍵的0~1個字節
7、所有數字鍵值以高字節優先被存儲以允許一個更高的索引壓縮
8、每個MyISAM類型的表都有一個AUTO_INCREMENT的內部列,當INSERT和UPDATE操作的時候該列被更新,同時AUTO_INCREMENT列將被刷新。所以說,MyISAM類型表的AUTO_INCREMENT列更新比InnoDB類型的AUTO_INCREMENT更快
9、可以把數據文件和索引文件放在不同目錄
10、每個字符列可以有不同的字符集
11、有VARCHAR的表可以固定或動態記錄長度
12、VARCHAR和CHAR列可以多達64KB
使用MyISAM引擎創建數據庫,將產生3個文件。文件的名字以表名字開始,擴展名之處文件類型:frm文件存儲表定義、數據文件的擴展名為.MYD(MYData)、索引文件的擴展名時.MYI(MYIndex)
MEMORY存儲引擎
MEMORY存儲引擎將表中的數據存儲到內存中,未查詢和引用其他表數據提供快速訪問。MEMORY主要特性有:
1、MEMORY表的每個表可以有多達32個索引,每個索引16列,以及500字節的最大鍵長度
2、MEMORY存儲引擎執行HASH和BTREE縮影
3、可以在一個MEMORY表中有非唯一鍵值
4、MEMORY表使用一個固定的記錄長度格式
5、MEMORY不支持BLOB或TEXT列
6、MEMORY支持AUTO_INCREMENT列和對可包含NULL值的列的索引
7、MEMORY表在所由客戶端之間共享(就像其他任何非TEMPORARY表)
8、MEMORY表內存被存儲在內存中,內存是MEMORY表和服務器在查詢處理時的空閑中,創建的內部表共享
9、當不再需要MEMORY表的內容時,要釋放被MEMORY表使用的內存,應該執行DELETE FROM或TRUNCATE TABLE,或者刪除整個表(使用DROP TABLE)
不同的存儲引擎都有各自的特點,以適應不同的需求,如下表所示
功能 | MYISAM | Memory | InnoDB | Archive |
存儲限制 | 256TB | RAM | 64TB | None |
支持事務 | No | No | Yes | No |
支持全文索引 | Yes | No | No | No |
支持數索引 | Yes | Yes | Yes | No |
支持哈希索引 | No | Yes | No | No |
支持數據索引 | No | N/A | Yes | No |
支持外鍵 | No | No | Yes | No |
總結:
如果要提供提交、回滾、崩潰恢復能力的事物安全(ACID兼容)能力,并要求實現并發控制,InnoDB是一個好的選擇
如果數據表主要用來插入和查詢記錄,則MyISAM引擎能提供較高的處理效率
如果只是臨時存放數據,數據量不大,并且不需要較高的數據安全性,可以選擇將數據保存在內存中的Memory引擎,MySQL中使用該引擎作為臨時表,存放查詢的中間結果
如果只有INSERT和SELECT操作,可以選擇Archive,Archive支持高并發的插入操作,但是本身不是事務安全的。Archive非常適合存儲歸檔數據,如記錄日志信息可以使用Archive
使用哪一種引擎需要靈活選擇,一個數據庫中多個表可以使用不同引擎以滿足各種性能和實際需求,使用合適的存儲引擎,將會提高整個數據庫的性能
三、mysql之數據類型、建表以及約束
1.數據類型介紹
MySQL中定義數據字段的類型對你數據庫的優化是非常重要的。
MySQL支持多種類型,大致可以分為三類:數值、日期/時間和字符串(字符)類型。
1)字符類型:char varchar text blob
2)數值類型:int bigint float decimal
int -> int
bigint -> long
float -> 成績
decimal -> 貨幣類型(精度,小數)
3)日期類型:date time datetime timestamp
date -> yyyy:MM:dd HH:mm:ss
time -> HH:mm:ss
datetime -> yyyy:MM:dd
timestamp(時間戳) -> 長整數
2、建表、刪表語句
1.表的創建 ★
/*
語法:
create table 表名(
列名 列的類型【(長度) 約束】,
列名 列的類型【(長度) 約束】,
列名 列的類型【(長度) 約束】,
...
列名 列的類型【(長度) 約束】
)
*/
案例:創建表Book
CREATE TABLE book(
id INT,#編號
bName VARCHAR(20),#圖書名
price DOUBLE,#價格
authorId INT,#作者編號
publishDate DATETIME#出版日期
);
DESC book;
案例:創建表author
CREATE TABLE IF NOT EXISTS author(
id INT,
au_name VARCHAR(20),
nation VARCHAR(10)
)
DESC author;
2.表的修改
/*
語法
alter table 表名 add|drop|modify|change column 列名 【列類型 約束】;
*/
①修改列名
ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;
②修改列的類型或約束
ALTER TABLE book MODIFY COLUMN pubdate TIMESTAMP;
③添加新列
ALTER TABLE author ADD COLUMN annual DOUBLE;
④刪除列
ALTER TABLE book_author DROP COLUMN annual;
⑤修改表名
ALTER TABLE author RENAME TO book_author;
DESC book;
3.表的刪除
DROP TABLE IF EXISTS book_author;
SHOW TABLES;
通用的寫法:
DROP DATABASE IF EXISTS 舊庫名;
CREATE DATABASE 新庫名;
DROP TABLE IF EXISTS 舊表名;
CREATE TABLE 表名();
4.表的復制
INSERT INTO author VALUES
(1,'村上春樹','日本'),
(2,'莫言','中國'),
(3,'馮唐','中國'),
(4,'金庸','中國');
SELECT * FROM Author;
SELECT * FROM copy2;
1.僅僅復制表的結構
CREATE TABLE copy LIKE author;
2.復制表的結構+數據
CREATE TABLE copy2
SELECT * FROM author;
只復制部分數據
CREATE TABLE copy3
SELECT id,au_name
FROM author
WHERE nation='中國';
僅僅復制某些字段
CREATE TABLE copy4
SELECT id,au_name
FROM author
WHERE 0;
3.主鍵(自動增長)、外鍵、非空等約束的使用
/*
含義:一種限制,用于限制表中的數據,為了保證表中的數據的準確和可靠性
分類:六大約束
NOT NULL:非空,用于保證該字段的值不能為空
比如姓名、學號等
DEFAULT:默認,用于保證該字段有默認值
比如性別
PRIMARY KEY:主鍵,用于保證該字段的值具有唯一性,并且非空
比如學號、員工編號等
UNIQUE:唯一,用于保證該字段的值具有唯一性,可以為空
比如座位號
CHECK:檢查約束【mysql中不支持】
比如年齡、性別
FOREIGN KEY:外鍵,用于限制兩個表的關系,用于保證該字段的值必須來自于主表的關聯列的值
在從表添加外鍵約束,用于引用主表中某列的值
比如學生表的專業編號,員工表的部門編號,員工表的工種編號
添加約束的時機:
1.創建表時
2.修改表時
約束的添加分類:
列級約束:
六大約束語法上都支持,但外鍵約束沒有效果
表級約束:
除了非空、默認,其他的都支持
主鍵和唯一的大對比:
保證唯一性 是否允許為空 一個表中可以有多少個 是否允許組合
主鍵√×至多有1個 √,但不推薦
唯一√√可以有多個 √,但不推薦
外鍵:
1、要求在從表設置外鍵關系
2、從表的外鍵列的類型和主表的關聯列的類型要求一致或兼容,名稱無要求
3、主表的關聯列必須是一個key(一般是主鍵或唯一)
4、插入數據時,先插入主表,再插入從表
刪除數據時,先刪除從表,再刪除主表
*/
CREATE TABLE 表名(
字段名 字段類型 列級約束,
字段名 字段類型,
表級約束
)
CREATE DATABASE students;
4.約束管理
一、創建表時添加約束
1.添加列級約束
/*
語法:
直接在字段名和類型后面追加 約束類型即可。
只支持:默認、非空、主鍵、唯一
*/
USE students;
DROP TABLE stuinfo;
CREATE TABLE stuinfo(
id INT PRIMARY KEY,#主鍵
stuName VARCHAR(20) NOT NULL UNIQUE,#非空
gender CHAR(1) CHECK(gender='男' OR gender ='女'),#檢查
seat INT UNIQUE,#唯一
age INT DEFAULT 18,#默認約束
majorId INT REFERENCES major(id)#外鍵
);
CREATE TABLE major(
id INT PRIMARY KEY,
majorName VARCHAR(20)
);
查看stuinfo中的所有索引,包括主鍵、外鍵、唯一
SHOW INDEX FROM stuinfo;
2.添加表級約束
/*
語法:在各個字段的最下面
【constraint 約束名】 約束類型(字段名)
*/
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
id INT,
stuname VARCHAR(20),
gender CHAR(1),
seat INT,
age INT,
majorid INT,
CONSTRAINT pk PRIMARY KEY(id),#主鍵
CONSTRAINT uq UNIQUE(seat),#唯一鍵
CONSTRAINT ck CHECK(gender ='男' OR gender = '女'),#檢查
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外鍵
);
SHOW INDEX FROM stuinfo;
通用的寫法:★
CREATE TABLE IF NOT EXISTS stuinfo(
id INT PRIMARY KEY,
stuname VARCHAR(20),
sex CHAR(1),
age INT DEFAULT 18,
seat INT UNIQUE,
majorid INT,
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)
);
二、修改表時添加約束
/*
1、添加列級約束
alter table 表名 modify column 字段名 字段類型 新約束;
2、添加表級約束
alter table 表名 add 【constraint 約束名】 約束類型(字段名) 【外鍵的引用】;
*/
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
id INT,
stuname VARCHAR(20),
gender CHAR(1),
seat INT,
age INT,
majorid INT
)
DESC stuinfo;
1.添加非空約束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NOT NULL;
2.添加默認約束
ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;
3.添加主鍵
①列級約束
ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;
②表級約束
ALTER TABLE stuinfo ADD PRIMARY KEY(id);
4.添加唯一
①列級約束
ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
②表級約束
ALTER TABLE stuinfo ADD UNIQUE(seat);
5.添加外鍵
ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id);
三、修改表時刪除約束
1.刪除非空約束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;
2.刪除默認約束
ALTER TABLE stuinfo MODIFY COLUMN age INT ;
3.刪除主鍵
ALTER TABLE stuinfo DROP PRIMARY KEY;
4.刪除唯一
ALTER TABLE stuinfo DROP INDEX seat;
5.刪除外鍵
ALTER TABLE stuinfo DROP FOREIGN KEY fk_stuinfo_major;
SHOW INDEX FROM stuinfo;
四、MySQL之CRUD
CRUD:創建(Create)、讀取(Read)、更新(Update)和刪除(Delete)
-
基礎查詢
/*
語法:
select 查詢列表 from 表名;
類似于:System.out.println(打印東西);
特點:
1、查詢列表可以是:表中的字段、常量值、表達式、函數
2、查詢的結果是一個虛擬的表格
*/
USE myemployees;
1.查詢表中的單個字段
SELECT last_name FROM t_mysql_employees;
2.查詢表中的多個字段
SELECT last_name,salary,email FROM t_mysql_employees;
3.查詢表中的所有字段
方式一:
SELECT
`employee_id`,
`first_name`,
`last_name`,
`phone_number`,
`last_name`,
`job_id`,
`phone_number`,
`job_id`,
`salary`,
`commission_pct`,
`manager_id`,
`department_id`,
`hiredate`
FROM
t_mysql_employees ;
方式二:
SELECT * FROM t_mysql_employees;
4.查詢常量值
SELECT 100;
SELECT 'john';
5.查詢表達式
SELECT 100%98;
6.查詢函數
SELECT VERSION();
7.起別名
/*
①便于理解
②如果要查詢的字段有重名的情況,使用別名可以區分開來
*/
方式一:使用as
SELECT 100%98 AS 結果;
SELECT last_name AS 姓,first_name AS 名 FROM t_mysql_employees;
方式二:使用空格
SELECT last_name 姓,first_name 名 FROM t_mysql_employees;
案例:查詢salary,顯示結果為 out put
SELECT salary AS "out put" FROM t_mysql_employees;
8.去重
案例:查詢員工表中涉及到的所有的部門編號
SELECT DISTINCT department_id FROM t_mysql_employees;
9.+號的作用
/*
java中的+號:
①運算符,兩個操作數都為數值型
②連接符,只要有一個操作數為字符串
mysql中的+號:
僅僅只有一個功能:運算符
select 100+90; 兩個操作數都為數值型,則做加法運算
select '123'+90;只要其中一方為字符型,試圖將字符型數值轉換成數值型
如果轉換成功,則繼續做加法運算
select 'john'+90;如果轉換失敗,則將字符型數值轉換成0
select null+10; 只要其中一方為null,則結果肯定為null
*/
案例:查詢員工名和姓連接成一個字段,并顯示為 姓名
SELECT CONCAT('a','b','c') AS 結果;
SELECT
CONCAT(last_name,first_name) AS 姓名
FROM
t_mysql_employees;
2.過濾和排序數據
1、過濾
2、在查詢中過濾行
3、where子句
4、比較運算
5、between
6、in
7、like
8、null
9、邏輯運算
3.過濾查詢案件
/*
語法:
select 查詢列表 from 表名 where 篩選條件;
分類:
一、按條件表達式篩選
簡單條件運算符:> < = != <> >= <=
案例1:查詢工資>12000的員工信息
SELECT
*
FROM
t_mysql_employees
WHERE
salary>12000;
案例2:查詢部門編號不等于90號的員工名和部門編號
SELECT
last_name,
department_id
FROM
t_mysql_employees
WHERE
department_id<>90;
二、按邏輯表達式篩選
邏輯運算符:
作用:用于連接條件表達式
&& || !
and or not
&&和and:兩個條件都為true,結果為true,反之為false
||或or:只要有一個條件為true,結果為true,反之為false
!或not: 如果連接的條件本身為false,結果為true,反之為false
案例1:查詢工資z在10000到20000之間的員工名、工資以及獎金
SELECT
last_name,
salary,
commission_pct
FROM
t_mysql_employees
WHERE
salary>=10000 AND salary<=20000;
案例2:查詢部門編號不是在90到110之間,或者工資高于15000的員工信息
SELECT
*
FROM
t_mysql_employees
WHERE
NOT(department_id>=90 AND department_id<=110) OR salary>15000;
三、模糊查詢
like
between and
in
is null
*/
案例1:查詢員工名中包含字符a的員工信息
select
*
from
employees
where
last_name like '%a%';#abc
案例2:查詢員工名中第三個字符為e,第五個字符為a的員工名和工資
select
last_name,
salary
FROM
t_mysql_employees
WHERE
last_name LIKE '__n_l%';
案例3:查詢員工名中第二個字符為_的員工名
SELECT
last_name
FROM
t_mysql_employees
WHERE
last_name LIKE '_$_%' ESCAPE '$';
2.between and
/*
①使用between and 可以提高語句的簡潔度
②包含臨界值
③兩個臨界值不要調換順序
案例1:查詢員工編號在100到120之間的員工信息
SELECT
*
FROM
t_mysql_employees
WHERE
employee_id <= 120 AND employee_id>=100;
----------------------
SELECT
*
FROM
t_mysql_employees
WHERE
employee_id BETWEEN 100 AND 120;
4.按表達式篩選
1.按條件表達式篩選
案例1:查詢工資>12000的員工信息
SELECT
*
FROM
t_mysql_employees
WHERE
salary>12000;
案例2:查詢部門編號不等于90號的員工名和部門編號
SELECT
last_name,
department_id
FROM
t_mysql_employees
WHERE
department_id<>90;
2.按邏輯表達式篩選
案例1:查詢工資z在10000到20000之間的員工名、工資以及獎金
SELECT
last_name,
salary,
commission_pct
FROM
t_mysql_employees
WHERE
salary>=10000 AND salary<=20000;
案例2:查詢部門編號不是在90到110之間,或者工資高于15000的員工信息
SELECT
*
FROM
t_mysql_employees
WHERE
NOT(department_id>=90 AND department_id<=110) OR salary>15000;
3.模糊查詢
/*
like
between and
in
is null|is not null
*/
1.like
/*
特點:
①一般和通配符搭配使用
通配符:
% 任意多個字符,包含0個字符
_ 任意單個字符
*、
案例1:查詢員工名中包含字符a的員工信息
select
*
from
employees
where
last_name like '%a%';#abc
案例2:查詢員工名中第三個字符為e,第五個字符為a的員工名和工資
select
last_name,
salary
FROM
t_mysql_employees
WHERE
last_name LIKE '__n_l%';
案例3:查詢員工名中第二個字符為_的員工名
SELECT
last_name
FROM
t_mysql_employees
WHERE
last_name LIKE '_$_%' ESCAPE '$';
2.between and
/*
①使用between and 可以提高語句的簡潔度
②包含臨界值
③兩個臨界值不要調換順序
*/
案例1:查詢員工編號在100到120之間的員工信息
SELECT
*
FROM
t_mysql_employees
WHERE
employee_id <= 120 AND employee_id>=100;
----------------------
SELECT
*
FROM
t_mysql_employees
WHERE
employee_id BETWEEN 100 AND 120;
3.in
/*
含義:判斷某字段的值是否屬于in列表中的某一項
特點:
①使用in提高語句簡潔度
②in列表的值類型必須一致或兼容
③in列表中不支持通配符
*/
案例:查詢員工的工種編號是 IT_PROG、AD_VP、AD_PRES中的一個員工名和工種編號
SELECT
last_name,
job_id
FROM
t_mysql_employees
WHERE
job_id = 'IT_PROT' OR job_id = 'AD_VP' OR JOB_ID ='AD_PRES';
------------------
SELECT
last_name,
job_id
FROM
t_mysql_employees
WHERE
job_id IN( 'IT_PROT' ,'AD_VP','AD_PRES');
4、is null
/*
=或<>不能用于判斷null值
is null或is not null 可以判斷null值
*/
案例1:查詢沒有獎金的員工名和獎金率
SELECT
last_name,
commission_pct
FROM
t_mysql_employees
WHERE
commission_pct IS NULL;
案例1:查詢有獎金的員工名和獎金率
SELECT
last_name,
commission_pct
FROM
t_mysql_employees
WHERE
commission_pct IS NOT NULL;
----------以下為×
SELECT
last_name,
commission_pct
FROM
t_mysql_employees
WHERE
salary IS 12000;
安全等于 <=>
案例1:查詢沒有獎金的員工名和獎金率
SELECT
last_name,
commission_pct
FROM
t_mysql_employees
WHERE
commission_pct <=>NULL;
案例2:查詢工資為12000的員工信息
SELECT
last_name,
salary
FROM
t_mysql_employees
WHERE
salary
5.order by子句
#、進階3:排序查詢
/*
語法:
select 查詢列表
from 表名
【where 篩選條件】
order by 排序的字段或表達式;
特點:
1、asc代表的是升序,可以省略
desc代表的是降序
2、order by子句可以支持 單個字段、別名、表達式、函數、多個字段
3、order by子句在查詢語句的最后面,除了limit子句
*/
1、按單個字段排序
SELECT * FROM t_mysql_employees ORDER BY salary DESC;
2、添加篩選條件再排序
案例:查詢部門編號>=90的員工信息,并按員工編號降序
SELECT *
FROM t_mysql_employees
WHERE department_id>=90
ORDER BY employee_id DESC;
3、按表達式排序
案例:查詢員工信息 按年薪降序
SELECT *,salary*12*(1+IFNULL(commission_pct,0))
FROM t_mysql_employees
ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;
4、按別名排序
案例:查詢員工信息 按年薪升序
SELECT *,salary*12*(1+IFNULL(commission_pct,0)) 年薪
FROM t_mysql_employees
ORDER BY 年薪 ASC;
5、按函數排序
案例:查詢員工名,并且按名字的長度降序
SELECT LENGTH(last_name),last_name
FROM t_mysql_employees
ORDER BY LENGTH(last_name) DESC;
6、按多個字段排序
案例:查詢員工信息,要求先按工資降序,再按employee_id升序
SELECT *
FROM t_mysql_employees
ORDER BY salary DESC,employee_id ASC;
排序練習
1.查詢員工的姓名和部門號和年薪,按年薪降序 按姓名升序
SELECT last_name,department_id,salary*12*(1+IFNULL(commission_pct,0)) 年薪
FROM t_mysql_employees
ORDER BY 年薪 DESC,last_name ASC;
2.選擇工資不在8000到17000的員工的姓名和工資,按工資降序
SELECT last_name,salary
FROM t_mysql_employees
WHERE salary NOT BETWEEN 8000 AND 17000
ORDER BY salary DESC;
3.查詢郵箱中包含e的員工信息,并先按郵箱的字節數降序,再按部門號升序
SELECT *,LENGTH(email)
FROM t_mysql_employees
WHERE email LIKE '%e%'
ORDER BY LENGTH(email) DESC,department_id ASC;
6.分組查詢
/*
功能:用作統計使用,又稱為聚合函數或統計函數或組函數
分類:
sum 求和、avg 平均值、max 最大值 、min 最小值 、count 計算個數
特點:
1、sum、avg一般用于處理數值型
max、min、count可以處理任何類型
2、以上分組函數都忽略null值
3、可以和distinct搭配實現去重的運算
4、count函數的單獨介紹
一般使用count(*)用作統計行數
5、和分組函數一同查詢的字段要求是group by后的字段
*/
1、簡單 的使用
SELECT SUM(salary) FROM t_mysql_employees;
SELECT AVG(salary) FROM t_mysql_employees;
SELECT MIN(salary) FROM t_mysql_employees;
SELECT MAX(salary) FROM t_mysql_employees;
SELECT COUNT(salary) FROM t_mysql_employees;
SELECT SUM(salary) 和,AVG(salary) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 個數
FROM t_mysql_employees;
SELECT SUM(salary) 和,ROUND(AVG(salary),2) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 個數
FROM t_mysql_employees;
2、參數支持哪些類型
SELECT SUM(last_name) ,AVG(last_name) FROM t_mysql_employees;
SELECT SUM(hiredate) ,AVG(hiredate) FROM t_mysql_employees;
SELECT MAX(last_name),MIN(last_name) FROM t_mysql_employees;
SELECT MAX(hiredate),MIN(hiredate) FROM t_mysql_employees;
SELECT COUNT(commission_pct) FROM t_mysql_employees;
SELECT COUNT(last_name) FROM t_mysql_employees;
3、是否忽略null
SELECT SUM(commission_pct) ,AVG(commission_pct),SUM(commission_pct)/35,SUM(commission_pct)/107 FROM t_mysql_employees;
SELECT MAX(commission_pct) ,MIN(commission_pct) FROM t_mysql_employees;
SELECT COUNT(commission_pct) FROM t_mysql_employees;
SELECT commission_pct FROM t_mysql_employees;
4、和distinct搭配
SELECT SUM(DISTINCT salary),SUM(salary) FROM t_mysql_employees;
SELECT COUNT(DISTINCT salary),COUNT(salary) FROM t_mysql_employees;
5、count函數的詳細介紹
SELECT COUNT(salary) FROM t_mysql_employees;
SELECT COUNT(*) FROM t_mysql_employees;
SELECT COUNT(1) FROM t_mysql_employees;
效率:
MYISAM存儲引擎下 ,COUNT(*)的效率高
INNODB存儲引擎下,COUNT(*)和COUNT(1)的效率差不多,比COUNT(字段)要高一些
6、和分組函數一同查詢的字段有限制,employee_id是最小的那個
SELECT AVG(salary),employee_id FROM t_mysql_employees;
分組函數練習
1.查詢公司員工工資的最大值,最小值,平均值,總和
SELECT MAX(salary) 最大值,MIN(salary) 最小值,AVG(salary) 平均值,SUM(salary) 和
FROM t_mysql_employees;
2.查詢員工表中的最大入職時間和最小入職時間的相差天數 (DIFFRENCE)
SELECT MAX(hiredate) 最大,MIN(hiredate) 最小,(MAX(hiredate)-MIN(hiredate))/1000/3600/24 DIFFRENCE
FROM t_mysql_employees;
SELECT DATEDIFF(MAX(hiredate),MIN(hiredate)) DIFFRENCE
FROM t_mysql_employees;
SELECT DATEDIFF('1995-2-7','1995-2-6');
3.查詢部門編號為90的員工個數
SELECT COUNT(*) FROM t_mysql_employees WHERE department_id = 90;
五、mysql之常用函數、聚合函數以及合并(union&union all)
1.笛卡爾集
select name,boyname from beauty,boys;
笛卡爾集會在下面條件下產生
– 省略連接條件
– 連接條件無效
– 所有表中的所有行互相連接
• 為了避免笛卡爾集, 可以在 WHERE 加入有 效的連接條件。
2.等值/連接連接
1、使用連接在多個表中查詢數據
在 WHERE 子句中寫入連接條件。
在表中有相同列時,在列名之前加上表名前綴
2、區分重復的列名
在不同表中具有相同列名的列可以用表的別名加以區分。
如果使用了表別名,則在select語句中需要使用表別名代替表名
表別名最多支持32個字符長度,但建議越少越好
3、表的別名
使用別名可以簡化查詢
使用表名前綴可以提高執行效率。
4、連接多表
連接 n個表,至少需要 n-1個連接條件。 例如:連接三個表,至少需要兩個連接條件。
案例:
含義:又稱多表查詢,當查詢的字段來自于多個表時,就會用到連接查詢
笛卡爾乘積現象:表1 有m行,表2有n行,結果=m*n行
發生原因:沒有有效的連接條件
如何避免:添加有效的連接條件
分類:
按年代分類:
sql92標準:僅僅支持內連接
sql99標準【推薦】:支持內連接+外連接(左外和右外)+交叉連接
按功能分類:
內連接:
等值連接
非等值連接
自連接
外連接:
左外連接
右外連接
全外連接
交叉連接
*/
SELECT * FROM beauty;
SELECT * FROM boys;
SELECT NAME,boyName FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;
一、sql92標準
1、等值連接
/*
① 多表等值連接的結果為多表的交集部分
②n表連接,至少需要n-1個連接條件
③ 多表的順序沒有要求
④一般需要為表起別名
⑤可以搭配前面介紹的所有子句使用,比如排序、分組、篩選
*/
案例1:查詢女神名和對應的男神名
SELECT NAME,boyName
FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;
案例2:查詢員工名和對應的部門名
SELECT last_name,department_name
FROM t_mysql_employees,departments
WHERE t_mysql_employees.`department_id`=t_mysql_departments.`department_id`;
2、為表起別名
/*
①提高語句的簡潔度
②區分多個重名的字段
注意:如果為表起了別名,則查詢的字段就不能使用原來的表名去限定
*/
查詢員工名、工種號、工種名
SELECT e.last_name,e.job_id,j.job_title
FROM t_mysql_employees e,jobs j
WHERE e.`job_id`=j.`job_id`;
3、兩個表的順序是否可以調換
查詢員工名、工種號、工種名
SELECT e.last_name,e.job_id,j.job_title
FROM t_mysql_jobs j,t_mysql_employees e
WHERE e.`job_id`=j.`job_id`;
4、可以加篩選
案例:查詢 有獎金 的員工名、部門名
SELECT last_name,department_name,commission_pct
FROM t_mysql_employees e,t_mysql_departments d
WHERE e.`department_id`=d.`department_id`
AND e.`commission_pct` IS NOT NULL;
案例2:查詢 城市名中第二個字符為o 的部門名和城市名
SELECT department_name,city
FROM t_mysql_departments t_mysql_d,locations l
WHERE d.`location_id` = l.`location_id`
AND city LIKE '_o%';
5、可以加分組
案例1:查詢 每個城市 的部門個數
SELECT COUNT(*) 個數,city
FROM t_mysql_departments d,t_mysql_locations l
WHERE d.`location_id`=l.`location_id`
GROUP BY city;
案例2:查詢 有獎金 的 每個部門 的 部門名和部門的領導編號 和該部門的最低工資
SELECT department_name,d.`manager_id`,MIN(salary)
FROM t_mysql_departments d,t_mysql_employees e
WHERE d.`department_id`=e.`department_id`
AND commission_pct IS NOT NULL
GROUP BY department_name,d.`manager_id`;
6、可以加排序
案例:查詢 每個工種 的 工種名和員工的個數,并且 按員工個數降序
SELECT job_title,COUNT(*)
FROM t_mysql_employees e,t_mysql_jobs j
WHERE e.`job_id`=j.`job_id`
GROUP BY job_title
ORDER BY COUNT(*) DESC;
7、可以實現三表連接?
案例:查詢員工名、部門名和所在的城市
SELECT last_name,department_name,city
FROM t_mysql_employees e,t_mysql_departments d,t_mysql_locations l
WHERE e.`department_id`=d.`department_id`
AND d.`location_id`=l.`location_id`
AND city LIKE 's%'
ORDER BY department_name DESC;
2、非等值連接
案例1:查詢員工的工資和工資級別
SELECT salary,grade_level
FROM t_mysql_employees e,t_mysql_job_grades g
WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
AND g.`grade_level`='A';
/*
select salary,employee_id from employees;
select * from job_grades;
CREATE TABLE job_grades
(grade_level VARCHAR(3),
lowest_sal int,
highest_sal int);
INSERT INTO job_grades
VALUES ('A', 1000, 2999);
INSERT INTO job_grades
VALUES ('B', 3000, 5999);
INSERT INTO job_grades
VALUES('C', 6000, 9999);
INSERT INTO job_grades
VALUES('D', 10000, 14999);
INSERT INTO job_grades
VALUES('E', 15000, 24999);
INSERT INTO job_grades
VALUES('F', 25000, 40000);
*/
3、自連接
案例:查詢 員工名和上級的名稱
SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
FROM t_mysql_employees e,t_mysql_employees m
WHERE e.`manager_id`=m.`employee_id`;
3.join鏈接
分類
內連接 [inner] join on
外連接
左外連接 left [outer] join on
右外連接 right [outer] join on
使用ON子句創建連接
自然連接中是以具有相同名字的列為連接條件的。
可以使用 ON 子句指定額外的連接條件。
這個連接條件是與其它條件分開的。
ON 子句使語句具有更高的易讀性。
join案例:
/*
語法:
select 查詢列表
from 表1 別名 【連接類型】
join 表2 別名
on 連接條件
【where 篩選條件】
【group by 分組】
【having 篩選條件】
【order by 排序列表】
分類:
內連接(★):inner
外連接
左外(★):left 【outer】
右外(★):right 【outer】
全外:full【outer】
交叉連接:cross
*/
一)內連接
/*
語法:
select 查詢列表
from 表1 別名
inner join 表2 別名
on 連接條件;
分類:
等值
非等值
自連接
特點:
①添加排序、分組、篩選
②inner可以省略
③ 篩選條件放在where后面,連接條件放在on后面,提高分離性,便于閱讀
④inner join連接和sql92語法中的等值連接效果是一樣的,都是查詢多表的交集
*/
1、等值連接
案例1.查詢員工名、部門名
SELECT last_name,department_name
FROM t_mysql_departments d
JOIN t_mysql_employees e
ON e.`department_id` = d.`department_id`;
案例2.查詢名字中包含e的員工名和工種名(添加篩選)
SELECT last_name,job_title
FROM t_mysql_employees e
INNER JOIN t_mysql_jobs j
ON e.`job_id`= j.`job_id`
WHERE e.`last_name` LIKE '%e%';
3. 查詢部門個數>3的城市名和部門個數,(添加分組+篩選)
①查詢每個城市的部門個數
②在①結果上篩選滿足條件的
SELECT city,COUNT(*) 部門個數
FROM t_mysql_departments d
INNER JOIN t_mysql_locations l
ON d.`location_id`=l.`location_id`
GROUP BY city
HAVING COUNT(*)>3;
案例4.查詢哪個部門的員工個數>3的部門名和員工個數,并按個數降序(添加排序)
①查詢每個部門的員工個數
SELECT COUNT(*),department_name
FROM t_mysql_employees e
INNER JOIN t_mysql_departments d
ON e.`department_id`=d.`department_id`
GROUP BY department_name
② 在①結果上篩選員工個數>3的記錄,并排序
SELECT COUNT(*) 個數,department_name
FROM t_mysql_employees e
INNER JOIN t_mysql_departments d
ON e.`department_id`=d.`department_id`
GROUP BY department_name
HAVING COUNT(*)>3
ORDER BY COUNT(*) DESC;
5.查詢員工名、部門名、工種名,并按部門名降序(添加三表連接)
SELECT last_name,department_name,job_title
FROM t_mysql_employees e
INNER JOIN t_mysql_departments d ON e.`department_id`=d.`department_id`
INNER JOIN t_mysql_jobs j ON e.`job_id` = j.`job_id`
ORDER BY department_name DESC;
二)非等值連接
查詢員工的工資級別
SELECT salary,grade_level
FROM t_mysql_employees e
JOIN t_mysql_job_grades g
ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`;
查詢工資級別的個數>20的個數,并且按工資級別降序
SELECT COUNT(*),grade_level
FROM t_mysql_employees e
JOIN t_mysql_job_grades g
ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`
GROUP BY grade_level
HAVING COUNT(*)>20
ORDER BY grade_level DESC;
三)自連接
查詢員工的名字、上級的名字
SELECT e.last_name,m.last_name
FROM t_mysql_employees e
JOIN t_mysql_employees m
ON e.`manager_id`= m.`employee_id`;
查詢姓名中包含字符k的員工的名字、上級的名字
SELECT e.last_name,m.last_name
FROM t_mysql_employees e
JOIN t_mysql_employees m
ON e.`manager_id`= m.`employee_id`
WHERE e.`last_name` LIKE '%k%';
二、外連接
/*
應用場景:用于查詢一個表中有,另一個表沒有的記錄
特點:
1、外連接的查詢結果為主表中的所有記錄
如果從表中有和它匹配的,則顯示匹配的值
如果從表中沒有和它匹配的,則顯示null
外連接查詢結果=內連接結果+主表中有而從表沒有的記錄
2、左外連接,left join左邊的是主表
右外連接,right join右邊的是主表
3、左外和右外交換兩個表的順序,可以實現同樣的效果
4、全外連接=內連接的結果+表1中有但表2沒有的+表2中有但表1沒有的
*/
引入:查詢男朋友 不在男神表的的女神名
SELECT * FROM t_mysql_beauty;
SELECT * FROM t_mysql_boys;
左外連接
SELECT b.*,bo.*
FROM t_mysql_boys bo
LEFT OUTER JOIN t_mysql_beauty b
ON b.`boyfriend_id` = bo.`id`
WHERE b.`id` IS NULL;
案例1:查詢哪個部門沒有員工
左外
SELECT d.*,e.employee_id
FROM t_mysql_departments d
LEFT OUTER JOIN t_mysql_employees e
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;
右外
SELECT d.*,e.employee_id
FROM t_mysql_employees e
RIGHT OUTER JOIN t_mysql_departments d
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;
全外
USE girls;
SELECT b.*,bo.*
FROM t_mysql_beauty b
FULL OUTER JOIN t_mysql_boys bo
ON b.`boyfriend_id` = bo.id;
交叉連接
SELECT b.*,bo.*
FROM t_mysql_beauty b
CROSS JOIN boys bo;
常見函數
1.字符函數
作用 | 函數 | 結果 |
轉小寫 | LOWER('SQL Course') | sql course |
轉大寫 | UPPER('SQL Course') | SQL COURSE |
拼接 | CONCAT('Hello','World') | HelloWorld |
截取 | SUBSTR('HelloWorld',1,5) | Hello |
長度 | LENGTH('HelloWorld') | 10 |
字符出現索引值 | INSTR('HelloWorld', 'W') | 6 |
字符截取后半段 | TRIM('H' FROM 'HelloWorld') |
elloWorld |
字符替換 | REPLACE('abcd','b','m') | amcd |
2.數字函數
作用 | 函數 | 結果 |
四舍五入 | ROUND(45.926, 2) | 45.93 |
截斷 | TRUNC(45.926, 2) | 45.92 |
求余 | MOD(1600, 300) | 100 |
3.日期函數
作用 | 函數 | 結果 |
獲取當前日期 | now() | |
將日期格式的字符轉換成指定格式的日期 |
STR_TO_DATE('7-7-2001','%m-%d-%Y') |
2001-07-07 |
將日期轉換成字符 | DATE_FORMAT(‘2023/8/14’,‘%Y年%m月%d日’) | 2023年08月14日 |
返回當前系統日期,不包含時間 |
SELECT CURDATE(); | |
返回當前時間,不包含日期 | SELECT CURTIME(); |
4.其他函數
#查看版本
SELECT VERSION();
#查看當前數據庫
SELECT DATABASE();
#查看當前用戶
SELECT USER();
5.流程控制函數
1.if函數: if else 的效果
SELECT IF(10<5,'大','小');
SELECT last_name,commission_pct,IF(commission_pct IS NULL,'沒獎金,呵呵','有獎金,嘻嘻') 備注
FROM t_mysql_employees;
2.case函數的使用一: switch case 的效果
/*
java中
switch(變量或表達式){
case 常量1:語句1;break;
...
default:語句n;break;
}
mysql中
case 要判斷的字段或表達式
when 常量1 then 要顯示的值1或語句1;
when 常量2 then 要顯示的值2或語句2;
...
else 要顯示的值n或語句n;
end
*/
/*案例:查詢員工的工資,要求
部門號=30,顯示的工資為1.1倍
部門號=40,顯示的工資為1.2倍
部門號=50,顯示的工資為1.3倍
其他部門,顯示的工資為原工資
*/
SELECT salary 原始工資,department_id,
CASE department_id
WHEN 30 THEN salary*1.1
WHEN 40 THEN salary*1.2
WHEN 50 THEN salary*1.3
ELSE salary
END AS 新工資
FROM t_mysql_employees;
3.case 函數的使用二:類似于 多重if
/*
java中:
if(條件1){
語句1;
}else if(條件2){
語句2;
}
...
else{
語句n;
}
mysql中:
case
when 條件1 then 要顯示的值1或語句1
when 條件2 then 要顯示的值2或語句2
。。。
else 要顯示的值n或語句n
end
*/
案例:查詢員工的工資的情況
如果工資>20000,顯示A級別
如果工資>15000,顯示B級別
如果工資>10000,顯示C級別
否則,顯示D級別
SELECT salary,
CASE
WHEN salary>20000 THEN 'A'
WHEN salary>15000 THEN 'B'
WHEN salary>10000 THEN 'C'
ELSE 'D'
END AS 工資級別
FROM t_mysql_employees;
);
6.分頁查詢
/*
應用場景:當要顯示的數據,一頁顯示不全,需要分頁提交sql請求
語法:
select 查詢列表
from 表
【join type join 表2
on 連接條件
where 篩選條件
group by 分組字段
having 分組后的篩選
order by 排序的字段】
limit 【offset,】size;
offset要顯示條目的起始索引(起始索引從0開始)
size 要顯示的條目個數
特點:
①limit語句放在查詢語句的最后
②公式
要顯示的頁數 page,每頁的條目數size
select 查詢列表
from 表
limit (page-1)*size,size;
size=10
page
10
2 10
320
*/
案例1:查詢前五條員工信息
SELECT * FROM t_mysql_employees LIMIT 0,5;
SELECT * FROM t_mysql_employees LIMIT 5;
案例2:查詢第11條——第25條
SELECT * FROM t_mysql_employees LIMIT 10,15;
案例3:有獎金的員工信息,并且工資較高的前10名顯示出來
SELECT
*
FROM
t_mysql_employees
WHERE commission_pct IS NOT NULL
ORDER BY salary DESC
LIMIT 10 ;
六、視圖
含義:虛擬表,和普通表一樣使用
mysql5.1版本出現的新特性,是通過表動態生成的數據
比如:舞蹈班和普通班級的對比
創建語法的關鍵字是否實際占用物理空間使用
視圖create view只是保存了sql邏輯增刪改查,只是一般不能增刪改
表create table保存了數據增刪改查
案例:查詢姓張的學生名和專業名
SELECT stuname,majorname
FROM stuinfo s
INNER JOIN major m ON s.`majorid`= m.`id`
WHERE s.`stuname` LIKE '張%';
CREATE VIEW v1
AS
SELECT stuname,majorname
FROM stuinfo s
INNER JOIN major m ON s.`majorid`= m.`id`;
SELECT * FROM v1 WHERE stuname LIKE '張%';
-
創建視圖
/*
語法:
create view 視圖名
as
查詢語句;
*/
USE myemployees;
1.查詢姓名中包含a字符的員工名、部門名和工種信息
①創建
CREATE VIEW myv1
AS
SELECT last_name,department_name,job_title
FROM employees e
JOIN departments d ON e.department_id = d.department_id
JOIN jobs j ON j.job_id = e.job_id;
②使用
SELECT * FROM myv1 WHERE last_name LIKE '%a%';
2.查詢各部門的平均工資級別
①創建視圖查看每個部門的平均工資
CREATE VIEW myv2
AS
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id;
②使用
SELECT myv2.`ag`,g.grade_level
FROM myv2
JOIN job_grades g
ON myv2.`ag` BETWEEN g.`lowest_sal` AND g.`highest_sal`;
3.查詢平均工資最低的部門信息
SELECT * FROM myv2 ORDER BY ag LIMIT 1;
4.查詢平均工資最低的部門名和工資
CREATE VIEW myv3
AS
SELECT * FROM myv2 ORDER BY ag LIMIT 1;
SELECT d.*,m.ag
FROM myv3 m
JOIN departments d
ON m.`department_id`=d.`department_id`;
2.視圖的修改
方式一:
/*
create or replace view 視圖名
as
查詢語句;
*/
SELECT * FROM myv3
CREATE OR REPLACE VIEW myv3
AS
SELECT AVG(salary),job_id
FROM employees
GROUP BY job_id;
方式二:
/*
語法:
alter view 視圖名
as
查詢語句;
*/
ALTER VIEW myv3
AS
SELECT * FROM employees;
3.刪除視圖
/*
語法:drop view 視圖名,視圖名,...;
*/
DROP VIEW emp_v1,emp_v2,myv3;
4.查看視圖
DESC myv3;
SHOW CREATE VIEW myv3;
5.視圖的更新
REATE OR REPLACE VIEW myv1
AS
SELECT last_name,email,salary*12*(1+IFNULL(commission_pct,0)) "annual salary"
FROM employees;
CREATE OR REPLACE VIEW myv1
AS
SELECT last_name,email
FROM employees;
SELECT * FROM myv1;
SELECT * FROM employees;
1.插入
INSERT INTO myv1 VALUES('張飛','zf@qq.com');
2.修改
UPDATE myv1 SET last_name = '張無忌' WHERE last_name='張飛';
3.刪除
DELETE FROM myv1 WHERE last_name = '張無忌';
具備以下特點的視圖不允許更新
①包含以下關鍵字的sql語句:分組函數、distinct、group by、having、union或者union all
CREATE OR REPLACE VIEW myv1
AS
SELECT MAX(salary) m,department_id
FROM employees
GROUP BY department_id;
SELECT * FROM myv1;
更新
UPDATE myv1 SET m=9000 WHERE department_id=10;
②常量視圖
CREATE OR REPLACE VIEW myv2
AS
SELECT 'john' NAME;
SELECT * FROM myv2;
更新
UPDATE myv2 SET NAME='lucy';
③Select中包含子查詢
CREATE OR REPLACE VIEW myv3
AS
SELECT department_id,(SELECT MAX(salary) FROM employees) 最高工資
FROM departments;
更新
SELECT * FROM myv3;
UPDATE myv3 SET 最高工資=100000;
④join
CREATE OR REPLACE VIEW myv4
AS
SELECT last_name,department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;
更新
SELECT * FROM myv4;
UPDATE myv4 SET last_name = '張飛' WHERE last_name='Whalen';
INSERT INTO myv4 VALUES('陳真','xxxx');
⑤from一個不能更新的視圖
CREATE OR REPLACE VIEW myv5
AS
SELECT * FROM myv3;
更新
SELECT * FROM myv5;
UPDATE myv5 SET 最高工資=10000 WHERE department_id=60;
⑥where子句的子查詢引用了from子句中的表
CREATE OR REPLACE VIEW myv6
AS
SELECT last_name,email,salary
FROM employees
WHERE employee_id IN(
SELECT manager_id
FROM employees
WHERE manager_id IS NOT NULL
);
更新
SELECT * FROM myv6;
UPDATE myv6 SET salary=10000 WHERE last_name = 'k_ing';
視圖練習
一、創建視圖emp_v1,要求查詢電話號碼以‘011’開頭的員工姓名和工資、郵箱
CREATE OR REPLACE VIEW emp_v1
AS
SELECT last_name,salary,email
FROM employees
WHERE phone_number LIKE '011%';
二、創建視圖emp_v2,要求查詢部門的最高工資高于12000的部門信息
CREATE OR REPLACE VIEW emp_v2
AS
SELECT MAX(salary) mx_dep,department_id
FROM employees
GROUP BY department_id
HAVING MAX(salary)>12000;
SELECT d.*,m.mx_dep
FROM departments d
JOIN emp_v2 m
ON m.department_id = d.`department_id`;
收錄于合集 #linux
11個
上一篇ansible的安裝及使用下一篇Linux中用戶與組