SQL 結構化查詢語言

導讀

MySql是我們常用的數據庫,javaEE常用幾款(Oracle,PostgreSQL,DB2或IBM),SQLite是用於嵌入式設備裏的小型數據庫,例如Android或IOS,而掌握SQL語句,就相當於掌握了所有的常見關係化數據庫,需要同學們重點掌握以及經常複習

MySQL數據庫服務器、數據庫和表的關係

  • 一般一個項目建一個數據庫,數據庫中又有一張張的table,table中的一條數據庫語句,相當於java中的實體bean類
  • 一個java類 對應數據庫中一張數據表,一個java對象 對應數據表中一條數據記錄

SQL語言

  • Structured Query Language(SQL語言),結構化查詢語言
    非過程性語言

  • 爲加強SQL的語言能力,各廠商增強了過程性語言的特徵

    • 如Oracle的PL/SQL 過程性處理能力
    • SQL Server、Sybase的T-SQL
  • SQL是用來存取關係數據庫的語言,具有查詢操縱定義控制關係型數據庫的四方面功能

SQL分類

  • DDL (數據定義語言)

    • 數據定義語言 - Data Definition Language
    • 用來定義數據庫的對象,如數據表、視圖、索引等
    • 即操作數據庫或表結構的
    • 所有數據庫相關操作語句,數據庫表結構操作語句都屬於DDL
  • DML (數據操縱語言)

    • 數據處理語言 - Data Manipulation Language
    • 在數據庫表中更新,增加和刪除記錄
    • update, insert, delete
  • DCL (數據控制語言)

    • 數據控制語言 – Data Control Language
    • 指用於設置用戶權限和控制事務語句
    • grant,revoke,if…else,while,begin transaction
  • DQL (數據查詢語言)

    • 數據查詢語言 – Data Query Language
    • select

SQL語句(重點)

  • 掌握SQL語句,相當於掌握了所有的常見關係化數據庫,需要重點掌握以及經常複習

  • 數據庫操作建議先在.txt文件,寫好再把光標移動語句最後,shift+home複製整句過去

  • 編寫sql語句沒有大小寫之分,注意不要拼錯單詞

  • MySQL5中文參考手冊 -> 部分不知道的字段可以通過這個文檔查詢


數據庫操作:

一 . 創建數據庫

  • 語法 : create database 數據庫名稱; (創建數據庫採用數據庫服務器默認字符集)
  • 複雜寫法 : create database 數據庫名稱 character set 字符集 collate 比較規則;

練習:
1. 創建一個名稱爲mydb1的數據庫。 create database mydb1;
2. 創建一個使用utf8字符集的mydb2數據庫。 create database mydb2 character set utf8;
3. 創建一個使用utf8字符集,並帶校對規則的mydb3數據庫。create database mydb3 character set utf8 collate utf8_bin;

==**補充: 每次創建一個數據庫在 數據存放目錄中生成一個文件夾 , 每個文件夾中存在 db.opt 存放默認字符集和校對規則
datadir=”C:/Documents and Settings/All Users/Application Data/MySQL/MySQL Server 5.5/Data/”**==


二 . 查詢數據庫

  • 語法 : show databases; —– 查看所有數據庫,沒有數據庫則返回沒數據null
  • 語法 : show create database 數據庫名; —— 查看數據編碼集

練習:
1. 查看當前數據庫服務器中的所有數據庫 show databases;
2. 查看前面創建的mydb2數據庫的定義信息 show create database mydb2;


三 . 刪除數據庫

  • 語法 : drop database 數據庫名稱;

練習:
1. 刪除前面創建的mydb1數據庫 drop database mydb1;


四 . 修改數據庫

  • 語法 : alter database 數據庫名稱 character set 字符集 collate 比較規則;

練習:
1. 修改mydb2字符集爲gbk; alter database mydb2 character set gbk;

==補充:==
1. 切換數據庫 use db_name; -> 當有多個數據庫的情況,需要use db_name; 先切換到要操作的數據庫
2. 查看當前正在使用數據庫: select database();

數據表操作:

一 . 創建數據表

  • 語法 : create table 表名(列名 類型(長度),列名 類型(長度)… );
格式 :

create table 表名(
   列名稱1 列名稱1值類型,
   列名稱2 列名稱2值類型,
   列名稱3 列名稱3值類型,
   列名稱4 列名稱4值類型
);

列名稱1值類型 是 mysql 中運行的值的類型

注意最後一句沒有  ,
  • MySQL 常用數據類型:
類型 說明
字符串型—String Varchar(可變值)、char(固定值) ->若兩者最大值都爲30,varchar如果數據只有20,最後就爲20;char如果數據只有20,會自動補齊,char比varchar效率高點
大數據類型—字節流,字符流 BLOB、TEXT
數值型–數值類型 (bit,byte,short,int,long,float,double) TINYINT 、SMALLINT、INT、BIGINT、FLOAT、DOUBLE
邏輯型 BIT 存放以爲數值 0 或者 1
日期型 DATE(只有日期)、TIME(只有時間)、DATETIME(日期和時間)、TIMESTAMP時間可以自動跟新(當前時間)
練習 :

創建一個員工表employee ---- 查看錶結構: desc 表名;
字段  屬性   
id  整形      int 
name    字符型    varchar(30)
gender  字符型    varchar(10)
birthday    日期型   date
entry_date  日期型   date
job 字符型          varchar(50)
salary  小數型          double
resume  大文本型        varchar(255)

create table employee(
   id int,
   name varchar(30),
   gender varchar(10),
   birthday date,
   entry_date date,
   job varchar(50),
   salary double,
   resume varchar(255)
);

==補充:==
1. 創建表時沒有指定字符集,將採用數據庫默認字符集
2. 創建表之前 必須使用use db_name 語法指定操作數據庫
3. 查看錶結構: desc 表名
4. 創建數據表時,只有字符串類型必須寫長度,而其他類型都有默認長度
5. 一個java類 對應數據庫中一張數據表,一個java對象 對應數據表中一條數據記錄


二 . 定義單表字段的約束

約束用來保證數據有效性和完整性
- 有效性: 類似日常生活防止姓名一樣,給個身份證號以保證身份的唯一性
- 完整性: 類似生活中一個人不告訴我們姓名就不讓他存數據,保證數據的完整性

  1. 定義主鍵約束(唯一,並且非空):

    primay key -> 信息記錄某個字段可以唯一區分其他信息記錄,這個字段就可以是主鍵

    如果列的類型爲數值型(int bigint),並且聲明爲主鍵,那麼通常會加上auto_increment,表示自動增長

  2. 唯一約束(不能重複,可以爲空):

    unique -> 一張表中可以有很多個唯一約束,只能有一個(兩個)作爲主鍵約束

  3. 非空約束(可以重複,不能爲空):

    not null

練習:

create table employee2(
   id int primary key auto_increment,
   name varchar(30) not null,
   gender varchar(10) not null,
   birthday date,
   entry_date date,
   job varchar(50),
   salary double not null,
   resume varchar(255) unique
);

三 . 修改數據表結構

  • 增加列 語法: alter table 表名 add 列名 類型(長度) 約束;
  • 修改現有列類型、長度和約束 語法:alter table 表名 modify 列名 類型(長度) 約束;
  • 修改現有列名稱 語法:alter table 表名 change 舊列名 新列名 類型(長度) 約束;
  • 刪除現有列 語法:alter table 表名 drop 列名;
  • 修改表名 rename table 舊錶名 to 新表名;

練習:
1. 修改表的字符集:—-alter table student character set utf8;
2. 在上面員工表的基本上增加一個image列: —-alter table employee add image varchar(100);
3. 修改job列,使其長度爲60。 —-alter table employee modify job varchar(60) not null;
4. 刪除gender列。 —-alter table employee drop gender ;
5. 表名改爲user。 —-rename table employee to user;
6. 修改表的字符集爲utf8 —- alter table user character set utf8;
7. 列名name修改爲username —– alter table user change name username varchar(20) unique not null;

==補充:==
1. 查看當前數據庫內所有表:show tables;
2. 查看當前數據表字符集 : show create table user;
3. 查看錶結構 : desc 表名;


四 . 刪除數據表

  • 語法:drop table 表名;

練習:
1. 刪除employee2表:drop table employee2;

數據表中數據記錄的增刪改查操作:

一 . 插入數據:

  • 語法一(全寫) :insert into 表名(列名,列名,列名…) values(值,值,值…);

    • 如:insert into employee2(id,name,gender,birthday,entry_date,job,salary,resume) values(1,’zs’,’female’,’1995-09-09’,’2015-12-09’,’developer’,15000,’a good developer’);
  • 語法二(只寫部分,字段值屬性爲空的可以不寫,不爲空的值要寫)

    • 如:insert into employee2 (id,name,gender,salary,resume) values(null,’haojie’,’male’,17000,’a hansome boy’);
  • 語法三(不寫字段名稱,只寫字段值,但是所有的字段值都要寫)

    • 如:insert into employee2 values(null,’linpeng’,’male’,’1994-09-09’,’2015-12-22’,’programmer’,16000,’a lady killer’);

==補充:==
1. 插入值 類型必須和 列類型匹配
2. 值長度不能超過 列定義長度
3. 值的順序和 列順序對應
4. 字符串和日期型值 必須寫 單引號
5. 插入空值 可以寫 null
6. 插入記錄後,使用select * from 表名; 查看錶信息

可能出現的bug:

插入一條中文記錄
insert into employee(id,name,job,salary) values(4,'小明','清潔員',1500);
出錯了:
ERROR 1366 (HY000): Incorrect string value: '\xC3\xF7' for column 'name' at row 1 ; 
錯誤原因:mysql client 採用默認字符集編碼 gbk 

查看系統所有字符集 : show variables like 'character%';

解決:修改客戶端字符集爲gbk

MYSQL中共有6個地方字符集 :client connetion result 和客戶端相關 、database server system 和服務器端相關 

第一種:
當前窗口臨時修改 set names gbk ;
* 只對當前窗口有效,關閉後就會失效

第二種:
配置mysql/my.ini 文件
[mysql] 客戶端配置
[mysqld] 服務器端配置 

修改客戶端字符集 [mysql] 後字符集  default-character-set=gbk

使用mysql -u root -p 密碼連入數據庫後,如果進行數據庫操作,直接操作,如果要進行數據表結構和數據記錄操作,必須先切換到操作的數據庫 use db;


二 . 數據記錄更改操作:

  • 語法: update 表名 set 列名=值,列名=值…. where條件語句;
    • 如果沒有where條件語句,默認修改所有行數據

練習:
1. 將所有員工薪水修改爲5000元。 —– update employee set salary = 5000;
2. 將姓名爲’zhangsan’的員工薪水修改爲3000元。 ——- update employee set salary = 3000 where name=’zhangsan’;
3. 將所有員工薪水修改爲5000元。 ——- update employee set salary=4000, job=’ccc’ where name=’lisi’;
4. 將wangwu的薪水在原有基礎上增加1000元。 ———— update employee set salary = salary+1000 where name =’wangwu’;


三 . 數據記錄的刪除操作:

  • 語法:delete from 表名 where條件語句;

    • 如果沒有where語句,將刪除表中 所有記錄
  • 語法: truncate table 表名;

練習:
1. 刪除表中名稱爲’zs’的記錄。—-delete from employee2 where name=’zs’;
2. 刪除表中所有記錄(DML語句)。—-delete from employee2;
3. 使用truncate刪除表中記錄。(先將表摧毀,然後再創建, 屬於DDL語句)—-truncate table employee2;

==補充:==

truncate 與 delete區別
1. truncate 刪除數據,過程先將整個表刪除,再重新創建
2. delete 刪除數據,逐行刪除記錄
3. truncate 屬於DDL,delete屬於DML——-事務管理只能對DML有效,被事務管理SQL語句可以回滾到SQL執行前狀態
4. truncate 效率要好於 delete


四 . 數據表記錄的查詢(DQL語句):

  • 語法一 : select [distinct] * | 列名,列名… from 表名;
    • select * from 表名; 查詢該表中所有列信息
    • select 列名,列名… from 表名; 查詢表中指定列的信息
    • distinct 用於去重
練習:

create table exam(
   id int primary key auto_increment,
   name varchar(20) not null,
   chinese double,
   math double,
   english double
); 

insert into exam values(null,'關羽',85,76,70);
insert into exam values(null,'張飛',70,75,70);
insert into exam values(null,'趙雲',90,65,95);

查詢表中所有學生的信息。 ---------  select * from exam; 

查詢表中所有學生的姓名和對應的英語成績。 ----- select name,english from exam;

過濾表中重複數據 (查詢英語成績,排除完全相同重複數據) ---- select distinct english from exam; 

  • 語法二 : select 列名 as 別名 from 表名;

練習:
1. 在所有學生分數上加10分特長分。 —- select name,chinese+10,math+10,english+10 from exam;
2. 統計每個學生的總分。——- select name,chinese+math+english from exam;
3. 使用別名表示學生分數。—– select name,chinese+math+english as 總分 from exam;
4. 在對列起別名時,as可以省略 select name,chinese+math+english as 總分 from exam; —— select name,chinese+math+english 總分 from exam;
5. select name,math from exam; 查詢name和math兩列的值
6. select name math from exam; 查詢name列值,起別名math

  • 語法三 : select 列名 from 表名 where條件語句

練習:
1. 查詢姓名爲關羽的學生成績 ——-select * from exam where name=’關羽’;
2. 查詢英語成績大於90分的同學 —– select * from exam where english > 90;
3. 查詢總分大於200分的所有同學 —– select * from exam where chinese+math+english > 200;

  • 語法四 : select * from 表名 order by 列名 asc|desc; —- asc升序 desc降序

練習:
1. 對數學成績排序後輸出。———– select * from exam order by math; 默認asc升序
2. 對總分排序按從高到低(降序)的順序輸出 ———— select * from exam order by math+chinese+english desc;
3. 對學生成績按照英語進行降序排序,英語相同學員按照數學降序 ————- select * from exam order by english desc,math desc;

  • 語法五:select 分組函數 from exam group by 列名; 按照某列進行分組統計 分組操作,就是具有相同數據記錄分到一組中,便於統計
練習:

create table orders(
    id int,
    product varchar(20),
    price float
);

insert into orders(id,product,price) values(1,'電視',900);
insert into orders(id,product,price) values(2,'洗衣機',100);
insert into orders(id,product,price) values(3,'洗衣粉',90);
insert into orders(id,product,price) values(4,'桔子',9);
insert into orders(id,product,price) values(5,'洗衣粉',90);

對訂單表中商品歸類後,顯示每一類商品的總價 ---- 需要按照商品名稱進行分組

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

在group by 語句後面 添加having 條件語句 ---- 對分組查詢結果進行過濾 

查詢購買了幾類商品,並且每類總價大於100的商品

select product,sum(price) from orders group by product having sum(price) > 100;


運算符:

  1. 相等= 不等 <>

  2. between …and… 在兩者之間取值 between 70 and 80 等價於 >=70 <=80 —– 注意前面那個數要比後面那個數要小

  3. in(值,值,值) 在指定值中任取一個 in(70,80,90) 值可以是70、80或者90

  4. **like ‘模糊查詢pattern’ 進行模糊查詢 ,表達式有兩個佔位符 % 任意字符串 _ 任意單個字符 例如: name like ‘張%’ 所有姓張學員
    name like ‘張_’ 所有姓張名字爲兩個字學員**

  5. is null 判斷該列值爲空

  6. and 邏輯與 or 邏輯或 not 邏輯非


練習:

查詢英語分數在 90100之間的同學。 -------- select * from exam where english>=90 and english <= 100;  select * from exam where english between 90 and 100;

查詢數學分數爲65,75,85的同學。 ---- select * from exam where math in(65,75,85); 

查詢所有姓趙的學生成績。---- select * from exam where name like '趙%';

查詢英語分>80,語文分>80的同學。 ---- select * from exam where english > 80 and chinese > 80;

insert into exam values(null,'劉備',null,55,38);

查詢語文沒有成績學員 select * from exam where chinese is null;

查詢語文有成績學員 select * from exam where chinese is not null;

聚集函數 指SQL語句中內置函數 ———- 分組函數(用於統計):

  1. count 統計查詢結果記錄條數 select count(*)|count(列名) from 表名;

練習:
1. 統計一個班級共有多少學生?———— select count( * ) from exam;
2. 統計英語成績大於90的學生有多少個? ——- select count( * ) from exam where english > 90;
3. 統計總分大於220的人數有多少? ——–select count( * ) from exam where chinese+math+english > 220;

  1. sum 統計某一列數據的和 select sum(列名) from 表名;

練習:
1. 統計一個班級數學總成績? —– select sum(math) from exam;
2. 統計一個班級語文、英語、數學各科的總成績 —- select sum(chinese),sum(math),sum(english) from exam;
3. 統計一個班級語文、英語、數學的成績總和 select sum(chinese+math+english) from exam; select sum(chinese)+sum(math)+sum(english) from exam;
4. **劉備語文null ,null進行所有運算 結果都是null
select sum(chinese)+sum(math)+sum(english) from exam; 含有劉備英語和數學成績
select sum(chinese+math+english) from exam; 不含劉備英語和數學成績**
5. **使用ifnull函數處理 null情況
select sum(ifnull(chinese,0)+ifnull(math,0)+ifnull(english,0)) from exam; 含有劉備英語和數學成績**
6. 統計一個班級語文成績平均分 —— select sum(chinese)/count( * ) from exam;

  1. avg 統計某一列平均值 select avg(列名) from 表名;

練習:
1. 求一個班級數學平均分? —- select avg(math) from exam;
2. 求一個班級總分平均分?—- select avg(ifnull(chinese,0)+ifnull(math,0)+ifnull(english,0)) from exam;

  1. max 統計一列最大值 min 統計一列最小值

練習:
1. 求班級最高分和最低分(數值範圍在統計中特別有用)select max(chinese+math+english) ,min(ifnull(chinese,0)+ifnull(math,0)+ifnull(english,0)) from exam;

==補充:==

where 和 having 條件語句的區別?
1. where 是在分組前進行條件過濾,having 是在分組後進行條件過濾 2. 使用where地方都可以用 having替換,但是having可以使用分組函數,而where後不可以用分組函數

小結select語句:

  • **S-F-W-G-H-O 組合 select … from … where … group by… having… order by … ;
    順序不能改變**

  • 解析順序 : from - where - group by - having - select - order by

多表設計:

多表設計(外鍵約束):

create table emp (
  id int primary key auto_increment,
  name varchar(20),
  job varchar(20),
  salary double
);

insert into emp values(null,'小麗','人力資源',4500);
insert into emp values(null,'小張','Java工程師',5000);
insert into emp values(null,'老李','財務經理',8000);
insert into emp values(null,'小劉','項目經理',10000);

create table dept(
   id int primary key auto_increment,
   name varchar(20)
);

insert into dept values(null,'人力資源部');
insert into dept values(null,'財務部');
insert into dept values(null,'技術研發部');

讓員工表和部門表發生關係,知道員工屬於哪個部門 ,在員工表添加部門id字段 
alter table emp add dept_id int ;
update emp set dept_id = 1 where name = '小麗';
update emp set dept_id = 2 where name = '老李';
update emp set dept_id = 3 where name = '小劉';
update emp set dept_id = 3 where name = '小張';

假設公司因爲財政問題,解散技術研發部 delete from dept where name ='技術研發部'; ----- 小張和小劉 失去了組織 

emp表 中dept_id字段 引用 dept表 id 字段 ------- 添加外鍵約束 (保證數據有效和完整性)
將emp表中dept_id 設置爲外鍵約束 alter table emp add foreign key(dept_id) references dept(id) ;

無法刪除技術研發部,因爲小劉和小張信息 依賴技術研發部 記錄 !!!!!

多表設計原則(瞭解):


  1. 多對多關係 : 僱員和項目關係

  • 一個僱員可以參與多個項目 , 一個項目可以由多個僱員參與
  • 建表原則:必須創建第三張關係表,在關係表中引用兩個實體主鍵 作爲外鍵
  • 關係表中每條記錄,代表一個僱員參與了一個項目

  • image


  1. 一對多關係: 用戶和博客關係

  • 一個用戶可以發表多篇博客 , 一個博客只能由一個作者
  • 建表原則:不需要創建第三方關係表,只需要在多方添加 一方主鍵作爲 外鍵

  • image


  1. 一對一關係 : 這種關係很少見到 負責人和工作室

  • 一個負責人 管理一個工作室 , 一個工作室 只有一個負責人
  • 建表規則:在任一方添加對方主鍵 作爲外鍵

笛卡爾積的學習:

多表查詢——笛卡爾積 
將A表中每條記錄 與 B表中每條記錄進行 匹配 獲得笛卡爾積 
select * from emp;
select * from dept;

select * from emp,dept; 顯示結果就是笛卡爾積 
笛卡爾積結果 就是 兩個表記錄乘積 例如A 表3條 B表4條 ---- 笛卡爾積 12條

笛卡爾積結果是無效的,必須從笛卡爾積中選取有效的數據結果 !!!

多表查詢 連接查詢 內連接查詢 
從A表中選擇一條記錄,去B表中找對應記錄 ----- 內連接 

必須A表和B表存在對應記錄纔會顯示 

create table A(A_ID int primary key auto_increment,A_NAME varchar(20) not null);
insert into A values(1,'Apple');
insert into A values(2,'Orange');
insert into A values(3,'Peach');

create table B(A_ID int primary key auto_increment,B_PRICE double);
insert into B values(1,2.30);
insert into B values(2,3.50);
insert into B values(4,null);

使用內連接 select * from a,b where a.a_id = b.a_id; 從笛卡爾積中篩選出有效的數據

* 內連接查詢結果條數 一定小於 兩個表記錄較多哪個表 ----- 例如 A表3條 B表5條 ---- 內連接結果條數 <= 5

select * from emp,dept where emp.dept_id = dept.id ; 將emp 表和dept 表進行內連接 
在內連接查詢時 添加條件,

查詢人力資源部有哪些 員工 ??
select * from emp,dept where emp.dept_id = dept.id and dept.name ='人力資源部'; 

查詢工資大於7000員工來自哪個部門? 
select * from emp,dept where emp.dept_id = dept.id and emp.salary > 7000;

select * from emp,dept where emp.dept_id = dept.id ; 寫法一
select * from emp inner join dept on emp.dept_id = dept.id ; 寫法二

擴展內容

MySQL 數據庫的備份和恢復

  • 備份命令 mysql/bin/mysqldump 將數據庫SQL語句導出
  • 語法:mysqldump -u 用戶名 -p 數據庫名 > 磁盤SQL文件路徑

例: 備份day12數據庫 — c:\day10.sql
cmd > mysqldump -u root -p day10 > c:\day10.sql 回車輸入密碼**

  • 恢復命令 mysql/bin/mysql 將sql文件導入到數據庫
  • 語法: mysql -u 用戶名 -p 數據庫名 < 磁盤SQL文件路徑

注意:導入SQL 必須手動創建數據庫,SQL不會創建數據庫

例: 將c:\day10.sql 導入 day10數據庫
cmd > mysql -u root -p day10 < c:\day10.sql 回車密碼

==補充知識==: 恢復SQL也可以在數據庫內部執行 source c:\day10.sql

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