MYSQL常識

 1.      MySQL安裝與配置

1.1.      安裝

將mysql-5.0.27-win32.rar壓縮文件解壓

 

運行Setup.exe

 

 

Typical: 常用模式, 包含一些常用的模塊

Complete: 完整模式, 包含所有模塊

Custom: 自定義, 根據需要選擇安裝

 

選擇所有組件, 安裝到本地硬盤

 

選擇安裝路徑

 

確定所選內容, 開始安裝

 

選擇跳過登陸註冊

 

安裝完成進入配置頁面

1.2.      配置

開始配置


Detailed: 詳細配置

Standard: 標準配置

我們需要根據用途選擇, 所以選詳細配置

 

服務器類型

關係到內存, 硬盤空間, 以及CPU使用

Developer: 程序員機器, 佔用儘量小的資源

Server: 服務器, 佔用中等資源

Dedicated: 數據庫專用服務器, 佔用所有資源

 

數據庫用途

 

數據存放路徑

默認爲安裝目錄

 

併發連接數

根據實際需要選擇

 

網絡設置

啓用TCP/IP連接: 如果不啓動, 只能本地操作

啓用精確模式: 不允許任何語法錯誤, 推薦開啓

 

默認編碼

Latin1, 不支持中文

UTF-8爲國際通用碼錶

由於我們Windows本地碼錶爲GBK, 也可選擇GBK, 省去亂碼的麻煩

 

系統選項

將MySQL安裝爲Windows服務, 自動啓動

將MySQL目錄添加到PATH環境變量, 以後可以直接從命令行啓動

 

權限選項

設置root用戶的密碼

 

運行配置項

1.3.      運行

在cmd.exe中輸入mysql –uroot –proot

或者mysql –uroot –p 回車之後輸入密碼, 密碼不可見

2.      數據庫概念

2.1.      數據庫服務器、數據庫和表之間的關係

所謂安裝數據庫服務器, 只是在機器上安裝了一個數據庫管理程序, 這個管理程序可以管理多個數據庫.

一般開發人員在設計項目的時候會針對每一個應用創建一個數據庫.

爲了保存每一類實體, 在一個數據庫中創建多個表.

 

 

 

客戶端

 

     服務器

 

 

數據庫程序

    表

數據庫

數據庫

    表

    表

2.2.      數據在數據庫中的存儲方式

id=1                      id=2

name=Tom            name=Jerry

age=18                  age=20

 

列(column)              列(column)        列(column)

id

name

     age

     1

    Tom

     18

     2

    Jerry

     20

 

 

 

 

行(row)

行(row)

 

 

每一行(一條記錄)對應Java中的一個對象

每一列對應對象的一個屬性

3.      操作庫

創建庫

CREATE DATABASE [IF NOT EXISTS] 數據庫名 [參數[ 參數] [ 參數]...];

參數:

       CHARACTER SET 碼錶名

       COLLATE 校對規則名   參見幫助文檔第10章

命令:show character set;可以顯示MySQL支持的字符集和校對規則

 

Show collation like ‘latin1%’;   顯示latin1字符集可以採用的校對規則

 

顯示庫

       SHOW DATABASES;

顯示數據庫創建語句

       SHOW CREATE DATABASE 數據庫名; 查看數據庫所採用的字符集

修改庫

       ALTER DATABASE 數據庫名[ 參數[ 參數][ 參數]...];

       注意: 不能改數據庫的名字

刪除庫

       DROP DATABASE [IF EXISTS] 數據庫名;

練習:

       創建一個數據庫db1

創建一個數據庫db2指定字符編碼, 校對規則

顯示所有數據庫

顯示db2的字符編碼

將db2的字符編碼設置爲gbk

刪除db2數據庫

4.      操作表

操作表之前使用需要先確定使用哪個數據庫

       USE 數據庫名

創建表

CREATE TABLE 表名(列名 類型[,列名 類型][,列名 類型]...);

具體類型說明可參見MySQL文檔第11章

查看所有表

       SHOW TABLES;

查看錶的創建語句

       SHOW CREATE TABLE 表名;

顯示錶結構

       DESC 表名;

修改表名

       RENAME TABLE 原表名 TO 新表名;

修改字符集

       ALTER TABLE 表名 CHARACTER SET 字符集名;

刪除表

       DROP TABLE 表名;

練習

       創建表employee, 包含以下字段:

id                          整型                            主鍵, 自動生成

name                     字符                            非空

gender                   字符或bit                    非空

birthday                 日期                           

entry_date             日期                            非空

position                 字符                           

salary                    小數                           

resume                  大文本

將表名改爲user

顯示錶結構

5.      操作列

追加列

    ALTER TABLE 表名 ADD 列名 類型[,列名 類型][,列名 類型]...;

修改列類型

       ALTER TABLE 表名 MODIFY 列名 類型[,列名 類型][,列名 類型]...;

修改列

       ALTER TABLE 表名 CHANGE COLUMN 原列名 新列名 類型;

刪除列

       ALTER TABLE 表名 DROP 列名;

練習

       添加一列用來存儲照片

將name長度修改爲30

將name改名爲username

刪除photo列

 

 

Insert into

Update

delete

select

6.      操作數據(增刪改)

6.1.      插入

語法:

       INSERT INTO 表名[(列名[,列名]...)] VALUES(值[,值]...);

注意事項:

       插入值類型必須與對應列的數據類型一致

       數據不能超出長度

       插入值得爲之必須與列名順序一致

       字符和日期數據要放在單引號中

       插入空值使用null

       如果不指定插入哪一列, 就是插入所有列

中文數據

       由於默認碼錶是utf8, 而cmd.exe的碼錶是gbk, 在插入中文數據的時候會報錯, 所以我們需要修改客戶端碼錶

       先查看系統變量: SHOW VARIABLES LIKE 'character%';

       修改客戶端碼錶: SET character_set_client=gbk;

       這樣就解決了中文插入的問題, 但在查詢數據的時候仍然顯示爲亂碼, 這是因爲mysql向cmd傳輸數據的時候使用的是utf8

       修改輸出數據的碼錶: SET character_set_results=gbk;

練習

       向user表中插入3條包含中文的數據

insert into user(id,username,gender,birthday,position,salary,resume)

values(1,'張三','男','1990-9-9','程序員',6000,'介紹');

 

insert into user(id,username,gender,birthday,position,salary,resume)

values(2,'李四','男','1990-9-9','程序員',6000,'介紹');

 

insert into user(id,username,gender,birthday,position,salary,resume)

values(3,'王五','男','1990-9-9','測試',6000,'介紹');

 

insert into user(id,username,gender,birthday,position,salary,resume)

values(4,'趙六','男','1990-9-9','美工 ',6000,'介紹');

 

6.2.      修改

語法

       UPDATE 表名 SET 列名=值[,列名=值]...[WHERE 條件語句];

注意事項

       WHERE子句選擇滿足條件的行進行更新, 如果不寫, 則更新所有行

練習

       將所有員工的薪水改爲5000

       將姓名爲張三的員工薪水改爲7000

       給李四加薪3000, 並且職位改爲經理

6.3.      刪除

語法

       DELETE FROM 表名 [where 條件語句]

注意事項

       如果不加where子句, 將刪除表中所有記錄

       delete只能用作刪除行, 不能刪除某一列的值, 需要用update

       在delete和update的時候需要注意表與表之間的關聯關係

       刪除表中所有數據可以使用: TRANCATE 表名, 這種方式會刪除舊錶重新創建, 在數據較多的時候使用

練習

       刪除所有美工

       刪除表中所有數據

7.      備份恢復數據庫

備份數據庫

       輸入quit退出mysql, 在cmd.exe中輸入:

mysqldump –u用戶名 –p密碼 數據庫名 > 文件名

恢復數據庫

       進入mysql.exe之後, 使用數據庫之後

       source 文件名

練習:

       備份指定數據庫, 刪除數據庫, 恢復

8.      操作數據(查詢)

8.1.      DISTINCT

語法

       SELECT [DISTINCT] 列名[, 列名]... FROM 表名

注意事項

       *可以替代列名, 表示所有列, 但是通常我們爲了提高代碼的可讀性, 不使用*

       DISTINCT爲過濾重複記錄

       如果DISTINCT後面跟多列, 是過濾掉多列合併之後的重複

練習

       查詢employee表中所有記錄

select id,username,gender,birthday,position,salary,resume from user;

       查詢employee表中所有人的薪水

select username,salary from user;

       查詢employee表中包含哪些崗位

8.2.      列名表達式

語法

       SELECT 列名|表達式[,列名|表達式]... FROM 表名

注意事項

       表達式只是顯示時起作用, 不會改變數據庫中的值

練習

       導入student.sql

source .....

查詢所有學生的總分

select name,chinese+math+english from student;

       查詢employee表, 將所有員工薪水*2顯示

       select username,salary*2 from user;

8.3.      AS

       SELECT 列名 AS 別名 FROM 表名

注意事項

       起別名時AS可以省略

       不會改變數據庫中的值

練習

       查詢所有學生總分, 別名爲總分

       select name '姓名',chinese+math+english '總分' from student;

 

8.4.      WHERE

語法

       SELECT 列名 FROM 表名 [WHERE 條件語句]

WHERE子句中的運算符

 

 

比較運算符

>, <, >=, <=, =, <>

注意不等於和Java中不同, 是<>

BETWEEN ... AND ...

某一區間內的值, 從 ... 到 ...

IN(列表)

在列表之中, 例: in(1,2,3) 代表1或2或3

LIKE(表達式)

模糊查詢, %代表多個字符, _代表單個字符

IS NULL

判斷是否爲NULL

 

  邏輯運算符

AND &&

與, 兩邊都爲TRUE結果爲TRUE

OR ||

或, 一邊爲TRUE結果就爲TRUE

NOT !

非, 將表達式結果取反

練習

       查詢英語分數在80-90分之間的

       select name,english from student where english>=80 and english<=90;

查詢語文分數爲81,82,83的學生

select name,english from student where english in(80,90,82);

查詢所有姓張的學生的成績

select name,english,math,chinese from student where name like '張%';

查詢除了姓張和姓李的學生總分

       select name,english,math,chinese

from student

where name not like '張%'

and name not like '李%';

 

select name,english,math,chinese

from student

where name like '張%'

or name like '李%';

 

8.5.      ORDER BY

語法

       SELECT 列名 FROM 表名 ORDER BY 列名 ASC|DESC;

注意事項

       ORDER BY 指定排序的列名可以是表中的列名, 也可以是SELECT語句後面起的別名

       ASC爲升序, DESC爲降序

       ORDER BY應在查詢語句的結尾

練習

       對數學成績排序後輸出

       select name,math from student order by math;

       查詢總分, 從高到低顯示

       select name '姓名',chinese+math+english '總分' from student order by 總分 desc;

       選擇所有姓張的學生的英語成績, 並從高到低排序

       select name,english from student where name like '張%' order by english desc;

       查詢學生成績, 按照語文從高到低排序, 如果語文相同, 按照英語從高到低排序

       select * from student order by chinese desc,english desc;

8.6.      COUNT函數

語法

SELECT COUNT(*)|COUNT(列名) from 表名 [WHERE 條件語句]

注意事項

       COUNT(列名)的方式是統計指定列中有多少條記錄, 不包括值爲NULL的

       COUNT(*)則是統計表中有多少條數據

       COUNT(DISTINCT 列名) 統計不重複的記錄數

       如果加上WHERE子句, 則是統計滿足條件的記錄

練習

       統計student表中有多少條記錄

       select count(*) from student;

       統計學生語文成績大於80的有多少人

       select count(*) from student where chinese>80;

       統計總分大於250的有多少人

       select count(*) from student where english+math+chinese>250;

       統計參加英語考試的有多少人

       select count(english) from student;

8.7.      SUM函數

語法

       SELECT SUM(列名) FROM 表名 [WHERE 條件語句];

注意事項

       計算指定列中所有記錄的和, 如果有WHERE子句則計算滿足條件的記錄

練習

       計算所有學生的數學成績總和

       select sum(math) from student;

       顯示所有學生的語文成績總和, 數學成績總和, 英語成績總和

       select sum(chinese),sum(math),sum(english) from student;

       計算所有學生的分數總和

       select sum(chinese)+sum(math)+sum(english) from student;

       統計英語平均分

       select sum(english)/count(*) from student;

select sum(english)/count(english) from student;

 

8.8.      AVG函數

語法

       SELECT AVG(列名) FROM 表名 [WHERE 條件語句];

注意事項

       計算指定列的平均值, 如果有WHERE子句, 則計算滿足條件的記錄

       AVG()統計平均數不包含NULL值

練習

       計算英語平均分

       select avg(english) from student;

       計算總分平均分, MySQL不支持組函數嵌套使用.

       select sum(english+math+chinese)/count(*) from student;

8.9.      MAX / MIN函數

語法

       SELECT MAX(列名) FROM 表名 [WHERE 條件語句];

       SELECT MIN(列名) FROM 表名 [WHERE 條件語句];

注意事項

       獲取指定列最高/最低值, NULL不參與統計

練習

       統計總分最高分和最低分

       select max(english+math+chinese),min(english+math+chinese) from student;

8.10.  GROUP BY(重點)

語法

       SELECT 列名 FROM 表名 GROUP BY 列名 [HAVING 條件語句]

注意事項

       按照某列歸類

       HAVING和WHERE類似, 但HAVING是作用於組, 其中可以使用組函數

SELECT列表中未包含在組函數中的列名, 只能是GROUP BY中的列名

HAVING中可以使用組函數, WHERE不能.

練習

       導入order.sql

       對訂單表歸類, 顯示購買過哪些商品

       select product from orders group by product;

       select distinct product from orders;

       對訂單表歸類, 顯示購買過哪些商品, 並顯示每種購買了幾個, 以及總價

       select product,count(product),sum(price) from orders group by product;

       查詢總價大於5000的商品有哪幾類

       select product,count(product),sum(price) sum_price from orders group by product having sum_price>5000;

 

9.      函數

9.1.      時間函數

注意date, datetime, timestamp之間的區別

 

ADDTIME(原時間, 增加值)       在某個時間上增加一段時間

       select addtime('18:23:01', '01:01:01');

select addtime(now(),'3:0:0');

CURRENT_DATE()                     當前日期

       select current_date();

CURRENT_TIME()                     當前時間

       select current_time();

CURRENT_TIMESTAMP()         當前時間戳

       select current_timestamp();

DATE(時間)                               返回制定時間的日期部分

       select date('2011-02-14 18:00:00');

DATE_ADD(日期,INTERVAL 增加值 類型)            在指定日期上對某個字段增加

       select date_add('2011-02-14 23:00:00', interval 10 month);

DATE_SUB(日期,INTERVAL 減少值 類型)             在指定日期上對某個字段減少

       select date_sub('2011-02-14 23:00:00', interval 1 year);

DATEDIFF(日期1, 日期2)         計算兩個日期之間的差值

       select datediff('2000-02-14', '2001-02-14');

NOW()          當前時間

       select now();

YEAR|MONTH|DATE|HOUR|MINUTE|SECOND(時間)            獲取指定時間的某個字段

       select year('2011-02-14 23:00:00');

       select hour('2011-02-14 23:00:00');

9.2.      字符串函數

CHARSET(字符串)                                                 返回字符串字符集

       select charset(name) from student;

CONCAT(字符串1[, 字符串2]... )                         連接字符串

       select concat('aaa', 'bbb', 'ccc');

INSTR(字符串, 子字符串)                                     查找子字符串出現位置, 注意序號從1開始

       select instr('abc', 'a');

UCASE(字符串)                                                     將字符串轉爲大寫

       select ucase('aBc');

LCASE(字符串)                                                      將字符串轉爲小寫

       select lcase('aBc');

LEFT(字符串, 長度)                                              從字符串左邊取指定長度個字符

       select left('aBc',2);

LENGTH(字符串)                                                   計算字符串長度

       select length('aBc');

REPLACE(字符串, 搜索字符串, 替換字符串)         將字符串中指定字符串替換爲其他字符串

       select replace('abbcbbd', 'bb', 'ee');

STRCMP(字符串1, 字符串2)                                逐個字符比較兩個字符串, 如果是包含關係, 則返回長度差值

       select strcmp('abcc', 'abde');

       select strcmp('abc', 'ab');

SUBSTRING(字符串, 開始座標[, 個數])         從字符串中截取

       select substring('abcdef', 3);

       select substring('abcdef', 3, 2);

LTRIM(字符串)                                                      去掉左邊空白

       select ltrim('    abc   ');

       select concat('--', ltrim('    abc   '), '--');

RTRIM(字符串)                                                     去掉右邊空白

       select concat('--', rtrim('    abc   '), '--');

TRIM(字符串)                                                       去掉左右兩邊空白

       select concat('--', trim('    abc   '), '--');

9.3.      數學函數

ABS(數字)                                        求絕對值

       select abs(10);

       select abs(-10);

BIN(十進制數)                                  將十進制轉換爲二進制

       select bin(5);

HEX(十進制數)                                 將十進制轉換爲十六進制

       select hex(10);

CONV(數字, 原進制, 目標進制)       轉換進制

       select conv(12, 10, 16);

       select conv(12, 10, 2);

       select conv(12, 16, 2);

CEILING(小數)                                 向上取整

       select ceiling(3.4);

FLOOR(小數)                                   向下取整

       select floor(3.4);

ROUND(小數)                                   四捨五入

       select round(3.4);

select round(3.5);

FORMAT(小數, 保留位數)                保留小數位

       select format(3.1415926, 2);

LEAST(值,值[,值]...)                         取最小值

       select least(1,2,3,4);

       select least('a', 'b', 'c', 'd');

GREATEST(值,值[,值]...)                   取最大值

       select greatest(1,2,3,4);

       select greatest('a', 'b', 'c', 'd');

MOD(數字, 數字)                             取餘

       select mod(3,2);

       select 3%2;

RAND()                                            生成隨機數, 14位小數, 0 <= n <= 1

       select rand();

10. 表的約束

約束的作用

限定某一列上的數據, 阻止非法數據錄入, 提高程序健壯性.

10.1.  唯一約束 unique

unique約束的字段在整張表中唯一, 不可重複, 不包括多個NULL

 

創建表時設置唯一

create table test (

       id int,

       name varchar(20) unique

);

 

刪除唯一約束

show create table test; 發現唯一索引名叫name

alter table test drop index name;

 

添加唯一約束

alter table test change name name varchar(20) unique;

10.2.  非空約束 not null

not null約束的字段不能爲空

 

創建表時設置非空

create table test1 (

       id int,

       name varchar(20) not null

);

 

刪除非空約束

alter table test1 change name name varchar(20);

 

添加非空約束

alter table test1 change name name varchar(20) not null;

10.3.  主鍵約束 primary key

通常我們在設計表的時候需要給每一條記錄一個獨有的標識, 我們就用主鍵來約束這個標識.

primary key用來標識一個字段, 這個字段是非空且唯一的.

 

創建表時設置主鍵

create table test2(

id int primary key,

name varchar(20)

);

 

刪除主鍵

alter table test2 drop primary key;

 

在制定列上添加主鍵

alter table test2 change id id int primary key;

alter table test2 add primary key(id);

 

設置主鍵自動增長

create table test3(

id int primary key auto_increment,

name varchar(20)

);

 

刪除自增長

alter table test3 change id id int;

 

設置自增長

alter table test3 change id id int auto_increment;

 

UUID主鍵

128位的2進制, 32位16進制加上4個-

java.util.UUID.randomUUID().toString()

3c2372a4-da2a-4470-b17a-f2e50ac79636

10.4.  外鍵約束 foreign key

foreign key約束某一列的值是參照另外一列

 

創建表時添加外鍵約束

create table husband(

       id int primary key,

       name varchar(20) not null

);

create table wife(

       id int primary key,

       name varchar(20) not null,

       husband_id int,

       constraint husband_id_fk foreign key(husband_id) references husband(id)

);

wife表的husband_id的值必須是husband表中的id

 

被外鍵引用的記錄不能刪除, 如果想要刪除某條被引用的記錄, 需要找到引用這條記錄的記錄, 解除關聯

 

被外鍵引用的表不能刪除, 如果想要刪除被引用的表, 需要刪除所有引用此表的外鍵

 

刪除外鍵約束

alter table wife drop foreign key husband_id_fk;

 

添加外鍵約束

alter table wife add constraint husband_id_fk foreign key(husband_id) references husband(id)

11. 表的設計

11.1.  單獨的實體

public class User{

    private int id;

    private String name;

    private int age;

}

 

user

 

id

name

age

1

張三

18

2

李四

20

3

王五

19

 

11.2.  一對多、多對一

foreign key

public class Employee {

    private int id;

    private String name;

    private Department department;

}

public class Department {

    private int id;

    private String name;

    private Set<Employee> employees;

}

一對多

多對一

 

 


department                                     employee

 

id

name

1

開發部

2

市場部

id

name

department_id

1

張三

1

2

李四

1

3

王五

2

 

多的一方設置外鍵

create table department(

       id int primary key auto_increment,

       name varchar(20)

);

 

create table employee(

       id int primary key auto_increment,

       name varchar(20),

       department_id int,

       constraint department_id_fk foreign key(department_id) references department(id)

);

 

insert into department(name) values('開發部');

insert into department(name) values('市場部');

insert into employee(name, department_id) values('張三',1);

insert into employee(name, department_id) values('李四',1);

insert into employee(name, department_id) values('王五',2);

11.3.  一對一

public class Husband {

    private int id;

    private String name;

    private Wife wife;

}

public class Wife {

    private int id;

    private String name;

    private Husband husband;

}

 

一對一

 

foreign key

 

 


unique

husband                                      wife

 

id

name

1

張三

2

李四

id

name

husband_id

1

冰冰

2

2

志玲

1

 

獨立外鍵, 沒有依賴關係, 兩個表的對象都可以獨立存在.

create table husband(

       id int primary key auto_increment,

       name varchar(20)

);

 

create table wife(

       id int primary key auto_increment,

       name varchar(20),

       husband_id int,

       constraint husband_id_fk foreign key(husband_id) references husband(id)

);

 

insert into husband(name) values('張三');

insert into husband(name) values('李四');

insert into wife(name, husband_id) values('冰冰',2);

insert into wife(name, husband_id) values('志玲',1);

 

 

public class Person {

    private int id;

    private String name;

    private IdCard idCard;

}

public class IdCard {

    private int id;

    private String num;

    private Person person;

}

一對一

 

foreign key

 

person                                        idcard

 

id

name

1

張三

2

李四

id

num

2

110123199009091234

1

120123200001011234

 

主鍵即外鍵, 分爲主表和從表, 從表依賴於主表, 從表中的對象不能單獨存在.

注意從表的主鍵, 不能自動增長.

 

create table person (

       id int primary key auto_increment,

       name varchar(20)

);

 

create table idcard (

       id int primary key,

       num varchar(20),

       constraint id_fk foreign key(id) references person(id)

);

 

insert into person(name) values('張三');

insert into person(name) values('李四');

insert into idcard(id,num) values(2,'110123199009091234');

insert into idcard(num,id) values('110123199009091234', 1);

11.4.  多對多

public class Student {

    private int id;

    private String name;

    private Set<Teacher> teachers;

}

public class Teacher {

    private int id;

    private String name;

    private Set<Student> students;

}

多對多

 

foreign key

foreign key

 

 


student                                                        student_teacher                            teacher

 

id

name

1

張三

2

李四

3

王五

student_id

teacher_id

1

1

2

1

2

2

3

2

id

name

1

張孝祥

2

黎活明

 

 

 

用一張關係表保存多對多的關係, 有兩列分別引用兩張表的主鍵, 並且這兩列組合起來成爲聯合主鍵

 

create table student (

       id int primary key auto_increment,

       name varchar(20)

);

 

create table teacher (

       id int primary key auto_increment,

       name varchar(20)

);

 

create table student_teacher(

       student_id int,

teacher_id int,

primary key(student_id, teacher_id),

constraint student_id_fk foreign key(student_id) references student(id),

constraint teacher_id_fk foreign key(teacher_id) references teacher(id)

);

 

insert into student(name) values('張三');

insert into student(name) values('李四');

insert into student(name) values('王五');

insert into teacher(name) values('zxx');

insert into teacher(name) values('lhm');

insert into student_teacher values(1,1);

insert into student_teacher values(2,1);

insert into student_teacher values(2,2);

insert into student_teacher values(3,2);

12. 多表查詢

12.1.  連接查詢

當我們要插敘的數據不只是在一張表中, 我們就需要使用多表連接查詢.

例如: 查詢員工所在的部門名稱, 查詢部門中員工名稱, 都需要查詢兩張表.

 

注意:

在多表連接查詢的時候, 如果沒有有效的連接條件, 所有表中的行會互相連接, 形成笛卡爾集.

爲了避免笛卡爾集, 可以再where後加入有效的連接條件

 

 

練習:

查詢出公司所有員工姓名, 所在部門名

查詢出開發部所有員工名

查詢出張三所在部門名稱

12.2.  多表連接

多張表連接查詢, 一張表外鍵引用另外一張表, 另外一張表再引用其他表.

例如: 員工表引用部門, 部門表引用城市表. 這時如果想根據員工查城市, 或者根據城市查員工就需要將三張表連接查詢

 

準備工作:

創建城市表, id主鍵自動生成, 帶有名稱

插入兩條記錄, 北京和上海

在部門表添加city_id, 外鍵引用城市表的id

將開發部的地址改爲北京, 市場部的地址改爲上海

 

練習:

查詢所有員工, 員工所屬部門以及部門所在城市

查詢北京的所有員工

12.3.  自連接

自己和自己連接, 當前表的外鍵引用自己的主鍵.

例如: 員工的經理也是員工, 應該在員工表中添加一列經理id. 之後添加一個外鍵, 引用員工表的主鍵.

 

準備工作:

在員工表中添加manager_id, 外鍵引用員工表id

插入趙六, 孫七. 分別屬於開發部和市場部.

將張三和李四的經理設置爲趙六, 王五經理設置爲孫七.

 

練習:

查詢王五的經理姓名

查詢趙六手下的員工名

12.4.  內連接、左外連接、右外連接(SQL99)

準備工作:

插入記錄周八, 部門爲空

插入部門財務部

 

1. 內連接

 

之前我們使用逗號和where子句進行的連接就是內連接. 標準語法應使用 inner join 和 on, 例如:

select e.name,d.name from employee e,department d where e.department_id=d.id;

select e.name,d.name from employee e inner join department d on e.department_id=d.id;

內連接會將兩張表完全匹配連接條件的記錄查詢出來, 不滿足的不會顯示

 

2. 左外連接

 

使用 left outer join 和 on 關鍵字進行連接查詢, 這時左表中不滿足條件的記錄也會被查詢出來

例如: 查詢所有員工的部門, 要將沒有部門的周八查詢出來. 這時需要查詢出員工表中所有記錄, 即使不滿足連接條件, 周八也要顯示.

 

3. 右外連接

 

使用 right outer join 和 on 關鍵字進行連接查詢, 這時右表中不滿足條件的記錄也會被查詢出來

例如: 查詢每個部門下都有哪些員工, 要將沒有員工的財務部顯示出來.

 

4. 全外連接

MySql不支持全外連接full outer join, 可以使用union distinct來實現.

 

練習:

使用左外連接查詢每個部門下都有哪些員工

使用右外連接查詢所有員工所屬部門

查詢所有員工名和所在部門, 以及部門所在城市.

查詢在上海工作的所有員工

查詢張三的經理姓名

12.5.  使用組函數的多表查詢

準備工作:

給員工表添加工資列, 並添加數據(5000-10000)

給員工表添加年齡列, 並添加數據(25-35)

 

練習:

查詢每個部門的平均工資

查詢每個部門的平均工資(包括沒有部門的).  

查詢每個城市的平均工資(包括沒有城市的).

查詢每個城市的平均工資(包括沒有城市的), 只顯示高於7000的, 並且按平均工資從高到低排序

查詢北京市年齡30歲以上員工的平均工資

 

select > from > join on > where > group by > having > order by

 

組函數練習題:

1.       組函數處理多行返回一行嗎?

2.       組函數是否計算空值?

3.       where子句是否可爲組函數進行過濾?

4.       查詢公司員工工資最大值, 最小值, 平均值, 總和.

5.       查詢公司各部門的工資最大值, 最小值, 平均值, 總和.

6.       查詢各個城市的員工人數.

7.       查詢員工最高工資和最低工資的差距.

8.       查詢各個經理手下員工的平均工資.

9.       統計員工人數, 顯示如下格式

13. 子查詢

一條查詢語句需要使用另一條查詢語句的結果.

例如: 查詢工資比張三高的員工

 

子查詢在主查詢之前完成

子查詢結果被主查詢所使用

子查詢要包含在括號內

子查詢放在條件右側

 

練習:

查詢工資最高的員工是誰

查詢所有城市中的最高平均工資是多少

查詢平均工資高於公司平均工資的部門有哪些

查詢公司所有經理的信息

查詢平均工資最低的部門中的最高工資

查詢平均工資最低的部門的經理的詳細信息

查詢25歲以上工資最高的員工的詳細信息

 

多行子查詢

ANY 集合中只要有一個元素滿足條件, 結果就成立.

ALL 集合中所有元素都滿足條件, 結果才成立

IN 相當於 =ANY

14. 中文亂碼問題

MySQL有六處使用了字符集, 分別爲:

 

client:             客戶端使用的字符集

connection:     連接數據庫的字符集, 如程序沒有指明, 就按照服務器端默認字符集.

database:        數據庫服務器中庫的字符集, 如建庫時沒有指明, 將使用服務器安裝時指定的字符集.

result:             數據庫給客戶端返回時使用的字符集, 如沒有指明, 使用服務器默認的字符集.

server:            服務器安裝時指定的默認字符集.

system:          數據庫系統使用的字符集.

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章