平時學習用到的SQL語句
阿新 • • 發佈:2020-07-20
一、建立和刪除資料庫
1、建立使用者
//建立使用者且置密碼,在MySQL中行,但在Oracle中行 ----必須在超級管理員身份下操作
create user hncu identified by '1234'
2、建立資料庫
//建立資料庫 並手動指定編碼格式
//錯,因為根據手冊的查詢,資料庫名應該在 EXISTS後面
CREATE DATABASE hncu IF NOT EXISTS DEFAULT CHARACTER SET 'utf8';
//改正:
CREATE DATABASE IF NOT EXISTS hncu DEFAULT CHARACTER SET 'utf8';
3、刪除資料庫
DROP DATABASE mydb2; //刪除資料庫
//查詢(顯示資料庫)
SHOW DATABASES; /*注:用Tab鍵補全程式碼,類似MyEclipse中的Alt+/ */
二、資料庫編碼問題
1、指定資料庫編碼
方法1:可以在MySQL的配置檔案如my.ini中指定:
default-character-set = GBK 或
default-character-set = utf8
方法2:在建立資料庫時自己指定,如:
CREATE DATABASE IF NOT EXISTS hncu DEFAULT CHARACTER SET 'utf8';
相比較而言,對我們來講,第2種方法更好。一是配置檔案是平臺,不能隨意改,而且通常是由DBA來做的,我們沒權設定,甚至MySQL都不在我們的電腦中。二是隻
要我們自己在建立資料庫時自己指定編碼,無論平臺預設配置的是什麼編碼,對我們沒有影響,一句話不依賴你的平臺----可移置及相容性好。
2、檢視資料庫編碼
SHOW VARIABLES; //查詢系統中的所有變數
SHOW VARIABLES WHERE variable_name LIKE 'character%'; //查詢系統中所有的編碼方面的引數
查詢結果:
character_set_client utf8 //客戶端編碼 (不同的客戶端顯示的可能不一樣,如cmd視窗和SQLyong) character_set_connection utf8 //客戶端連線資料庫時用的編碼 character_set_database gbk //資料庫的預設編碼(一般來講,這是由my.ini配置檔案定的。這是沒進資料庫時的通用編碼) character_set_filesystem binary //這是資料庫自己儲存資料檔案時用的編碼,跟我們關係不大 character_set_results utf8 //查詢之後的結果集的編碼 character_set_server gbk //MySQL資料庫伺服器自己的編碼 iso8859-1在這裡稱Latin1 character_set_system utf8 character_set_dir MySQL安裝目錄 \share\charsets
對我們來講,為了不出現亂碼,必須保證client和connection的編碼一致,否則就會亂碼。
character_set_database 資料庫的編碼必須要能夠支援中文,否則輸入中文有問題的
3、設定(修改)資料編碼
//如何設定指定的編碼
set character_set_client=gbk;
SET character_set_client=gbk;
SHOW VARIABLES WHERE variable_name LIKE 'character%';
SELECT * FROM stud;//原來的資料顯示正常
INSERT INTO stud VALUES(1011,'城院',20,88,'數計學院');
SELECT * FROM stud;//剛剛插入的那條記錄,是亂碼 //因為我們這裡client是gbk,而connection是utf8,不一致了
SET character_set_connection=gbk;//已經把client和connection設成gbk,一致了
INSERT INTO stud VALUES(1012,'城院2',20,88,'數計學院');
SELECT * FROM stud;//顯示剛剛插入的那條記錄,還是亂碼。因為資料庫表stud的編碼是utf8,而我們客戶端與它的連線都是gbk
綜上,client、connection、我們所訪問的資料庫的編碼 這三者都要一致且應該是支援中文的編碼
上面只能保證新增到資料庫中的漢字不會出現亂碼。
如果讀取出來,還要看results、所訪問的資料庫的編碼和我們java程式碼中的解碼是否一致。
三、建立表格
//建立表格
CREATE TABLE stud(
id INT PRIMARY KEY,
sname VARCHAR(30) ,
age INT);
-------------------------------------------------------------varchar(20) ----可變的char陣列,類似Java當中的String
char(20) ----固定長度的char陣列
//SQL語言 全部忽略大小寫----大小寫不敏感
-------------------------------------------------------------
四、對錶格操作
USE hncu;
SHOW TABLES;//查詢(顯示)表格
DESC stud; //檢視資料表student的表結構
1、往資料表中插入資料
INSERT INTO stud VALUES( 1003,'Rose',22 );
//插入記錄,當資料不全時,要指定列名
INSERT INTO stud(id,sname,age,score) VALUES(1010,'李小明',25,90);//未指定列名的方式賦值時,必須要給全,預設值不給也不行
INSERT INTO a(id,sname) VALUES(1,'Tom'); //錯:UNIQUE限定該列的值必須唯一(可以為,但最多隻能有一個)
INSERT INTO a(id,sname) VALUES(2,'Tom'); //對,性別未賦,則用預設
//效能優化:指定列名的方式效能更好!
2、查詢資料
SELECT * FROM stud;//查詢表中所有的資料
SELECT sname,age FROM stud; //只查詢(顯示)表中的指定列
3、刪除資料
DELETE FROM stud WHERE age=30; //刪除年齡為30的表記錄
4、更新資料
UPDATE stud SET sname='傑克' WHERE sname='Jack'; //更改資料
5、更改表結構ALTER TABLE (新增一列)
ALTER TABLE stud ADD COLUMN score NUMERIC(4,2);
※※※※※建立聯合主鍵※※※※※
ALTER TABLE sj ADD CONSTRAINT sj_pk PRIMARY KEY(studId,jectId);
//新增外來鍵約束1(為sj表的studId欄位新增外來鍵student(id)約束)
ALTER TABLE sj ADD CONSTRAINT sj_fk1 FOREIGN KEY(studId) REFERENCES student(id);
//新增外來鍵約束2(為sj表的jectId欄位新增外來鍵ject(id)約束)
ALTER TABLE sj ADD CONSTRAINT sj_fk2 FOREIGN KEY(jectId) REFERENCES ject(id);
6、建立檢視
CREATE VIEW studView AS SELECT * FROM stud WHERE score>=60;
SELECT * FROM studview;
五、對錶查詢操作中的那些事
INSERT INTO stud VALUES(1004,'張三',38,60);
INSERT INTO stud VALUES(1005,'王三',30,60);
INSERT INTO stud VALUES(1006,'王五',30,60);
INSERT INTO stud VALUES(1007,'王五六',30,80);
※1、範圍查詢
//查詢年齡在24-26之間的學生資訊
1)連續區間內的查詢
SELECT * FROM stud WHERE age>=24 AND age<27;
2)用BETWEEN是左右都包含,如下功能是[24,26]
SELECT * FROM stud WHERE age BETWEEN 24 AND 26;
3)離散的多個
SELECT * FROM stud WHERE age=24 OR age=38;
SELECT * FROM stud WHERE age IN(24,26,30);
※2、模糊查詢LIKE 引數:%(任意匹配), _(匹配一個)
//查詢姓“王”的學生資訊
SELECT * FROM stud WHERE sname LIKE '王%'
//查詢姓“王”且名為單字的學生資訊
SELECT * FROM stud WHERE sname LIKE '王_';
//查詢姓“王”且名為雙字的學生資訊
SELECT * FROM stud WHERE sname LIKE '王__';
//查詢姓名中包含“五”字的學生資訊
SELECT * FROM stud WHERE sname LIKE '%五%';
※3、範圍查詢和模糊查詢聯合
//查詢姓名中包含“五”字 且 年齡大於30 的學生資訊
SELECT * FROM stud WHERE sname LIKE '%五%' AND age>30;
※4、空值查詢
//查詢無名英雄學生的資訊(VARCHAR)
SELECT * FROM stud WHERE sname IS ;
//查詢沒有年齡資訊的學生
//錯:SELECT * FROM stud WHERE age==;
SELECT * FROM stud WHERE age IS ;
※5、聚合函式
1)COUNT 統計表格的行數
SELECT COUNT(*) AS TEMPTABLE FROM stud;//as temptable 含義:就是將查詢出的結果(表格的行數)另命名為:temptable
SELECT COUNT(1) AS TEMPTABLE FROM stud;
//統計有年齡值的學生人數
SELECT COUNT(age) AS TEMPTABLE FROM stud;
//統計有年齡值且有分數值的學生人數
SELECT COUNT(age) AS TEMPTABLE FROM stud WHERE score IS NOT ;
2)AVG 統計平均分且取整(注:AVG函式只統計非的資料記錄)
SELECT ROUND(AVG(score)) FROM stud; //這種方式一般不用,因為列名是自動生成的,我們在程式中不好訪問
SELECT ROUND(AVG(score)) AS averageScore FROM stud;
3)SUM 分數求和
SELECT SUM(score) AS ss FROM stud;
4)MAX年齡最大值
SELECT MAX(age) AS maxAge FROM stud;
※6 、WHERE子句+ IN子句
//查詢年齡最小的那個人的名字
SELECT sname FROM stud WHERE age=(SELECT MIN(age) FROM stud);
SELECT sname FROM stud WHERE age IN(SELECT MIN(age) FROM stud);
※7、排序
SELECT * FROM stud GROUP BY age ASC; //不重複排序(即年齡相同的,只顯示第一個0
SELECT * FROM stud GROUP BY age ASC; //顯示出所有年齡段
SELECT * FROM stud ORDER BY age ASC; //普通排序--升序
SELECT * FROM stud ORDER BY age DESC; //普通排序--降序
※8、distinct(不重複的值)
SELECT DISTINCT sname,age FROM stud GROUP BY age DESC;
※9、EXISTS 判斷括號內的內容是否存在----注意,下面的例子,只要存在年齡為26的學生,就會輸出所有資料
SELECT * FROM stud WHERE EXISTS( SELECT * FROM stud WHERE age=26 );
※10、演示分組
ALTER TABLE stud ADD COLUMN dept VARCHAR(20);
UPDATE stud SET dept='資訊學院' WHERE score>=65;
UPDATE stud SET dept='通訊學院' WHERE score=60;
UPDATE stud SET dept='土木學院' WHERE score<60;
SELECT * FROM stud;
//分組計算
//按學院計算平均分(每個學員的平均分)
SELECT dept,AVG(score) AS '學院平均分' FROM stud GROUP BY dept;
※11、字串處理函式
SELECT * FROM stud WHERE sname='AAA';
SELECT * FROM stud WHERE TRIM(sname)='AAA';//去掉左右的空格
SELECT * FROM stud WHERE LTRIM(RTRIM(sname))='AAA';//和上面等價
UPDATE stud SET dept='數計學院' WHERE id=1011;
SELECT LEFT(TRIM(sname),2) FROM stud; //取去掉空格後的左起2個字元
SELECT REVERSE(TRIM(sname)) FROM stud;
CREATE TABLE person(
id INT,
sname VARCHAR(30) ,
age INT
);
ALTER TABLE person ADD CONSTRAINT person_pk PRIMARY KEY(id);//更靈活
DROP TABLE person;
sname VARCHAR(30) NOT ,
age INT
); //用NOT 限制非空輸入
※12、性別欄位(例如:資料庫存0、1 而顯示出來為男、女)
一般不定義成BOOLEAN型,因為有的資料庫不支援,為考慮相容,通常用CHAR(1)
CREATE TABLE a(
id INT UNIQUE,
sname VARCHAR(10),
sex CHAR(1) DEFAULT '0'
);
//顯示性別 (真實值與顯示值之間的轉換)
SELECT * FROM a;
SELECT id,sname,(CASE sex WHEN '0' THEN '女' WHEN '1' THEN '男' ELSE '' END) xb FROM a;
SELECT id,sname,(CASE sex WHEN '0' THEN '女' WHEN '1' THEN '男' ELSE '' END) AS xb FROM a;
SELECT id,sname,(CASE WHEN sex='0' THEN '女' WHEN sex='1' THEN '男' ELSE '' END) AS xb FROM a;
※13、無關子查詢
//需求:具有同齡人的學生
SELECT * FROM stud;
SELECT * FROM stud WHERE age IN ( SELECT age FROM stud GROUP BY age HAVING COUNT(age)>=2 ) ORDER BY age DESC;
//練練別名
SELECT * FROM stud AS xs WHERE age IN ( SELECT age FROM xs GROUP BY age HAVING COUNT(age)>=2 ) ORDER BY age DESC;
//需求2:不但具有同齡人,而且年齡大於等於30的學生
//法1
SELECT * FROM stud WHERE age IN ( SELECT age FROM stud GROUP BY age HAVING COUNT(age)>=2 AND age>=30 ) ORDER BY age DESC;
//法2
SELECT * FROM stud WHERE age>=30 AND age IN ( SELECT age FROM stud GROUP BY age HAVING COUNT(age)>=2 ) ORDER BY age DESC;
※14、固定搭配
SELECT * FROM + WHERE + ORDER BY(要放在最後)
GROUP BY + HAVING
※15、關係查詢
NAME VARCHAR(10),
sex CHAR(1),
wife INT,
husband INT
);
INSERT INTO person VALUES(1,'小花','0',0,3);
INSERT INTO person VALUES(2,'玉芬','0',0,4);
INSERT INTO person VALUES(3,'張三','1',1,0);
INSERT INTO person VALUES(4,'李四','1',2,0);
INSERT INTO person VALUES(5,'王五','1',0,0);
1)一對一關係的操作:查出每對夫妻的姓名
CREATE VIEW w AS SELECT * FROM person WHERE sex='0';
CREATE VIEW m AS SELECT * FROM person WHERE sex='1';
//不利用表與表之間的關係
SELECT w.NAME AS 妻子, m.NAME AS 丈夫 FROM w,m WHERE w.husband=m.id AND m.wife=w.id;
//現在更先進的方式:利用表間的關係
SELECT w.NAME AS 妻子, m.NAME AS 丈夫 FROM w INNER JOIN m ON w.husband=m.id AND m.wife=w.id;
SELECT * FROM person;
2)一對多的關係 程式碼演示
//步驟1:畫E-R圖
//步驟2:分別建實體表,並給多方的表新增外來鍵約束
CREATE TABLE person2(
id VARCHAR(32) PRIMARY KEY,
pname VARCHAR(30),
sex CHAR(1)
);
CREATE TABLE car(
id VARCHAR(32) PRIMARY KEY,
cname VARCHAR(30),
price NUMERIC(10,2),
pid VARCHAR(32),
CONSTRAINT car_fk FOREIGN KEY(pid) REFERENCES person2(id)
);
DROP TABLE car;
//步驟3:為兩個表新增測試資料
//實體表1
INSERT INTO person2(id,pname,sex) VALUES('P001','Jack','1');
INSERT INTO person2(id,pname,sex) VALUES('P002','Tom','1');
INSERT INTO person2(id,pname,sex) VALUES('P003','Rose','0');
INSERT INTO person2(id,pname,sex) VALUES('P004','Mary','0');
INSERT INTO person2(id,pname,sex) VALUES('P005','Mike','1');
SELECT * FROM person2;
////實體表2
INSERT INTO car(id,cname,price,pid) VALUES('C001','BMW',123.5,'P001');
INSERT INTO car(id,cname,price,pid) VALUES('C002','Benz',123.5,'P001');
INSERT INTO car(id,cname,price,pid) VALUES('C003','BMW',223.5,'P001');
INSERT INTO car(id,cname,price,pid) VALUES('C011','BMW',83.5,'P003');
INSERT INTO car(id,cname,price,pid) VALUES('C012','Benz',100,'P003');
INSERT INTO car(id,cname,price,pid) VALUES('C013','Audi',223.5,'P003');
INSERT INTO car(id,cname,price,pid) VALUES('C021','BMW',88.5,'P004');
INSERT INTO car(id,cname,price,pid) VALUES('C022','QQ',10,'P004');
INSERT INTO car(id,cname,price,pid) VALUES('C023','Audi',73,'P005');
INSERT INTO car(id,cname,price) VALUES('C033','Audi',1000);
//該句程式碼執行錯誤,因為編號為P006的人在Person2表中不存在,這就是參照完整性
INSERT INTO car(id,cname,price,pid) VALUES('C033','Audi',1000,'P006');
SELECT * FROM car;
//查詢:哪些人有什麼樣的車 (用"表名.列名"的形式訪問列,如果列名不重複,可以省略表名)
//利用一方的主鍵和“多方”的外來鍵進行關聯
SELECT person2.pname,car.cname FROM person2,car WHERE person2.id=car.pid;
//查詢Jack有什麼車
SELECT person2.pname,car.cname FROM person2,car WHERE person2.id=car.pid AND person2.pname='Jack' ;
//查詢哪些人有兩輛以上的車
SELECT person2.pname,COUNT(pname) AS 車數量 FROM person2,car WHERE person2.id=car.pid GROUP BY pname HAVING COUNT(pname)>=2 ORDER BY 車
數量;
SELECT * FROM person2 WHERE id IN ( SELECT pid FROM car GROUP BY pid HAVING COUNT(pid)>=2 );
※16、關聯查詢
//查詢哪些人沒有車
SELECT * FROM person2 WHERE id NOT IN( SELECT pid FROM car );
//用左關聯(LEFT JOIN)來查詢:哪些人有什麼樣的車(沒車的也是一種情況,要顯示)
SELECT person2.pname,car.cname,car.price FROM person2 LEFT JOIN car ON person2.id=car.pid ORDER BY person2.id;
//用內關聯(INNER JOIN)來查詢:哪些人有什麼樣的車(沒車的不顯示)
SELECT person2.pname,car.cname,car.price FROM person2 INNER JOIN car ON person2.id=car.pid ORDER BY person2.id;
//查詢每輛車的銷售情況(如果有主人就顯示,沒有則顯示)
SELECT person2.pname,car.cname,car.price FROM person2 RIGHT JOIN car ON person2.id=car.pid ORDER BY person2.id;
(+在左邊時 右關聯 ,+右邊時 左關聯)
\--------------------------------------------------
DELETE FROM person2 WHERE id='P005';
CREATE TABLE student(
id VARCHAR(32) PRIMARY KEY,
NAME VARCHAR(30),
CREATE TABLE ject(
price NUMERIC(5,2)
);
CREATE TABLE sj(
studId VARCHAR(32) NOT ,
jectId VARCHAR(32)
);
//建立聯合主鍵
//新增測試資料
//學生表
INSERT INTO student(id,NAME,age) VALUES('S001','Jack',25);
INSERT INTO student(id,NAME,age) VALUES('S002','Tom',24);
INSERT INTO student(id,NAME,age) VALUES('S003','張三',23);
INSERT INTO student(id,NAME,age) VALUES('S004','李四',24);
INSERT INTO student(id,NAME,age) VALUES('S005','Rose',25);
SELECT * FROM student;
//課程表
INSERT INTO ject(id,NAME,price) VALUES('J001','Java',25);
INSERT INTO ject(id,NAME,price) VALUES('J002','MySQL',30);
INSERT INTO ject(id,NAME,price) VALUES('J003','Oracle',55.9);
INSERT INTO ject(id,NAME,price) VALUES('J004','軟體工程',20.25);
INSERT INTO ject(id,NAME,price) VALUES('J005','WEB開發',125);
SELECT * FROM ject;
//選課表
INSERT INTO sj(studId,jectId) VALUES('S001','J001');
INSERT INTO sj(studId,jectId) VALUES('S001','J002');
INSERT INTO sj(studId,jectId) VALUES('S001','J003');
INSERT INTO sj(studId,jectId) VALUES('S002','J001');
INSERT INTO sj(studId,jectId) VALUES('S002','J003');
INSERT INTO sj(studId,jectId) VALUES('S003','J001');
INSERT INTO sj(studId,jectId) VALUES('S003','J002');
INSERT INTO sj(studId,jectId) VALUES('S004','J003');
INSERT INTO sj(studId,jectId) VALUES('S005','J001');
SELECT * FROM sj;
應用測試
//查詢哪些人選了哪些課 ----要求顯示:人名,課程名
//採用的是92標準
SELECT student.name,ject.NAME FROM student,ject,sj WHERE student.id=sj.studId AND sj.jectId=ject.id;
//採用96標準
SELECT student.name,ject.NAME FROM student
INNER JOIN sj ON student.id=sj.studId
INNER JOIN ject ON sj.jectId=ject.id;
//查詢哪些人沒有選課(左關聯)
SELECT student.name,ject.NAME FROM student
LEFT JOIN sj ON student.id=sj.studId
LEFT JOIN ject ON sj.jectId=ject.id WHERE ject.NAME IS ;
//查詢哪些課沒人選(右關聯)
SELECT student.name,ject.NAME FROM student
RIGHT JOIN sj ON student.id=sj.studId
RIGHT JOIN ject ON sj.jectId=ject.id WHERE student.NAME IS ;
//左右關聯可以相互轉換,如把上面的程式碼用左關聯
SELECT student.name,ject.NAME FROM jec
LEFT JOIN sj ON ject.id=sj.jectId
LEFT JOIN student ON sj.studId=student.id WHERE student.NAME IS
六、儲存過程
//定義儲存過程p1 // “DELIMITER
”當作結束標誌(否則預設是把“;“號當作結束標記),這樣儲存過程中的語句結束符";"就不會當作過程的結束
記。
DELIMITER$$
CREATE PROCEDURE p1
BEGIN
SELECT * FROM stud;
INSERT INTO stud(id,sname,age,score,dept) VALUES(1014,'劉三豐',33,55,'通訊學院');
END$$
DELIMITER; //把結束標記還原回來
CALL p1; //呼叫儲存過程p1
1、帶引數的儲存過程
DELIMITER$$
CREATE PROCEDURE p2(IN id INT, IN nm VARCHAR(30) )
BEGIN
INSERT INTO stud(id,sname) VALUES(id,nm);
END$$
DELIMITER ;
DROP PROCEDURE p2;
CALL p2(1015,'吊絲');
2、有返回值的儲存過程----引數與變數問題( @變數名 ,一個@為使用者變數,兩個@即 @@為全域性的系統變數 )
DELIMITER$$
CREATE PROCEDURE p3(IN id INT, IN nm VARCHAR(30), OUT num INT )
SELECT COUNT(*) INTO num FROM stud;
CALL p3(1016,'無名',@aa);
SELECT @aa; //輸出變數aa的值
七、事務處理
START TRANSACTION
DELETE FROM stud WHERE id=1015;
DELETE FROM stud WHERE id=1014;
SELECT * FROM stud;
ROLLBACK / COMMIT;
◎採用事務的java程式設計
try{
st.execute("START TRANSACTION;");
st.execute("DELETE FROM stud WHERE id=1015;");
st.execute("DELETE FROM stud WHERE id=1014;");
....
st.execute(" commit; ");
}catch(Exception e){
rollback;}