SQL筆記(MySQL)

創建數據庫

CREATE DATABASE dream;
創建數據庫並指定默認的字符集

CREATE DATABASE dream 
DEFAULT CHARACTER SET utf8;
選擇數據庫
USE dream;
刪除數據庫
DROP DATABASE IF EXISTS dream;
顯示數據庫
SHOW DATABASES;
顯示數據表
SHOW TABLES;
顯示數據表中各個列的屬性
SHOW COLUMNS FROM writers;
顯示創建數據庫的mysql語句
SHOW CREATE DATABASE dream;
顯示創建數據表的mysql語句
SHOW CREATE TABLE writers;

創建數據表

CREATE TABLE writers
(
   writer_id INTEGER NOT NULL,
   writer_name VARCHAR(50) NOT NULL,
   sex CHAR(1),
   birthday DATE,
   nationality VARCHAR(50),
   PRIMARY KEY (writer_id)
) ENGINE=InnoDB 
  DEFAULT CHARSET='utf8';
CREATE TABLE books
(
   book_id INTEGER NOT NULL,
   title VARCHAR(100) NOT NULL,
   author_id INTEGER,
   publisher VARCHAR(100),
   isbn VARCHAR(13),
   price DOUBLE,
   PRIMARY KEY (book_id),
   FOREIGN KEY (author_id) REFERENCES writers (writer_id)
) ENGINE=InnoDB 
  DEFAULT CHARSET='utf8';
CREATE TABLE book_sales
(
   sales_id INTEGER AUTO_INCREMENT PRIMARY KEY,
   book_id INTEGER UNIQUE NOT NULL,
   sales INTEGER DEFAULT 0,
   KEY (book_id)
) ENGINE=InnoDB 
  DEFAULT CHARSET='utf8';

用檢索出的數據創建表

CREATE TABLE writers_bak AS
SELECT * FROM writers;
修改表字段類型
ALTER TABLE writers MODIFY writer_name VARCHAR(100);
添加表字段
ALTER TABLE writers ADD email VARCHAR(100);
刪除表字段
ALTER TABLE writers DROP COLUMN email;
修改表字段名

# change和modify都可修改字段的定義,change後面需要寫兩次列名,但是change可以修改字段名,modify不能。
ALTER TABLE writers CHANGE sex gender CHAR(1);
添加主鍵
ALTER TABLE writers ADD PRIMARY KEY (writer_id);
添加外鍵
ALTER TABLE books ADD CONSTRAINT FK_books_writers 
   FOREIGN KEY (author_id) REFERENCES writers (writer_id);
添加唯一約束
ALTER TABLE writers ADD UNIQUE (writer_name);
刪除表
DROP TABLE IF EXISTS writers_bak_20140815;
重命名錶
RENAME TABLES writers_bak TO writers_bak_20140815;
檢索單個列
SELECT writer_name FROM writers;
檢索多個列
SELECT writer_name, sex, nationality FROM writers;
檢索所有列
SELECT * FROM writers;
DISTINCT關鍵字,過濾重複行
SELECT DISTINCT nationality FROM writers;
LIMIT字句,限制結果範圍
SELECT * FROM writers LIMIT 3;    # 最多不返回3個結果
SELECT * FROM writers LIMIT 2, 5; # 檢索從行2開始的5行,行從0開始計數
使用完全限定名
SELECT writers.nationality FROM dream.writers;
排序數據
SELECT * FROM writers ORDER BY birthday;
多列排序,排序順序按列出現的順序
SELECT * FROM writers ORDER BY nationality, birthday;
指定排序方向,DESC降序、ASC升序,默認爲ASC升序
# 如果想在多個列上進行降序排序,則每個列都要指定DESC關鍵字
SELECT * FROM writers ORDER BY nationality DESC, birthday ASC;

隨機排序

SELECT * FROM writers ORDER BY RAND();
WHERE字句過濾數據
SELECT * FROM writers WHERE nationality = '中國';
SELECT * FROM writers WHERE nationality != '中國'; # <>也表示不等於
SELECT * FROM writers WHERE birthday < '1900-01-01';
SELECT * FROM writers WHERE birthday >= '1980-01-01'
SELECT * FROM writers WHERE birthday BETWEEN '1900-01-01' AND '1999-12-31';
SELECT * FROM writers WHERE birthday IS NULL;
AND操作符
SELECT * FROM writers WHERE sex = 'M' AND nationality = '中國';
OR操作符(AND操作符的優先級大於OR操作符)
SELECT * FROM writers WHERE sex = 'F' OR birthday >= '1980-01-01';
IN操作符
SELECT * FROM writers WHERE nationality IN ('中國', '美國');
NOT操作符
SELECT * FROM writers WHERE nationality NOT IN ('中國', '美國');
LIKE操作符
SELECT * from writers WHERE writer_name like '張%'; # %匹配任意個字符
SELECT * from writers WHERE writer_name like '韓_'; # _匹配一個字符
用正則表達式進行檢索
SELECT * FROM writers WHERE writer_name REGEXP '[a-zA-Z]+[\s·]?[a-zA-Z]+';
使用計算字段
SELECT CONCAT('[', nationality, ']', writer_name) FROM writers;
使用別名,關鍵字AS可以省略
SELECT YEAR(NOW()) - YEAR(birthday) AS age FROM writers;
使用函數
SELECT UPPER(writer_name) FROM writers; # 文本函數
SELECT YEAR(NOW()) - YEAR(birthday) AS age FROM writers; # 日期時間函數
SELECT ABS(-1); # 數值處理函數
聚集函數
SELECT AVG(price) FROM books;   # 忽略列值爲NULL的行
SELECT COUNT(price) FROM books; # 忽略列值爲NULL的行
SELECT COUNT(*) FROM books;     # 不會忽略列值爲NULL的行
SELECT MAX(price) FROM books;   # 忽略列值爲NULL的行
SELECT MIN(price) FROM books;   # 忽略列值爲NULL的行
SELECT SUM(price) FROM books;   # 忽略列值爲NULL的行
聚集不同的值
SELECT COUNT(DISTINCT publisher) FROM books; # 其他聚集函數也可以指定DISTINCT,COUNT(*)不允許指定
分組
SELECT nationality, COUNT(*) FROM writers GROUP BY nationality;
SELECT author_id, publisher FROM books GROUP BY author_id, publisher;
分組過濾 HAVING

# HAVING與WHERE的區別:
# HAVING是基於分組聚集值過濾,WHERE是基於特定行值顧慮;
# 可以這樣理解:WHERE是在數據分組前過濾,HAVING是在數據分組後過濾。

SELECT nationality, COUNT(*) 
FROM writers 
GROUP BY nationality
HAVING COUNT(*) > 1;
完整SELECT字句出現順序
SELECT nationality, COUNT(*) AS cnt
FROM writers
WHERE sex = 'M'
GROUP BY nationality
ORDER BY cnt
LIMIT 5;
子查詢

SELECT * FROM books WHERE author_id IN (
   SELECT writer_id FROM writers WHERE writer_name LIKE '張%'
);
子查詢作爲計算字段(相關子查詢)
# 查詢每個作家出書的數量
SELECT writer_name, 
          (SELECT COUNT(*) FROM books b WHERE b.author_id = w.writer_id) AS book_num
FROM writers w
ORDER BY book_num DESC;
表連接(笛卡爾積)
SELECT title, writer_name, publisher, isbn, price
FROM books b, writers w
WHERE b.author_id = w.writer_id;
內部連接
SELECT title, writer_name, publisher, isbn, price
FROM books b INNER JOIN writers w
ON b.author_id = w.writer_id;
多表連接
SELECT writer_name, title, sales
FROM writers w, books b, book_sales s
WHERE w.writer_id = b.author_id
AND b.book_id = s.book_id;
自連接
# 查詢比某本書價格更高的書
SELECT b1.title, b1.price
FROM books b1, books b2
WHERE b1.price > b2.price
AND b2.title = '嫌疑人X的獻身';
自然連接
SELECT * FROM books NATURAL JOIN book_sales;

左外連接

SELECT title, sales
FROM books b LEFT OUTER JOIN book_sales s
ON b.book_id = s.book_id;
右外連接
SELECT title, sales
FROM book_sales s RIGHT OUTER JOIN books b
ON b.book_id = s.book_id;
表連接與分組結合
SELECT nationality, COUNT(book_id) AS book_num
FROM books b INNER JOIN writers w
ON b.author_id = w.writer_id
GROUP BY w.nationality ;
組合查詢 UNION
SELECT title FROM books NATURAL JOIN book_sales WHERE sales > 5000
UNION
SELECT title FROM books, writers WHERE author_id = writer_id AND nationality = '中國';
組合查詢UNION,包含重複行 (默認情況下,UNION會過濾掉重複行)
SELECT title FROM books NATURAL JOIN book_sales WHERE sales > 5000
UNION ALL
SELECT title FROM books, writers WHERE author_id = writer_id AND nationality = '中國';
組合查詢UNION,排序
SELECT title FROM books NATURAL JOIN book_sales WHERE sales > 5000
UNION
SELECT title FROM books, writers WHERE author_id = writer_id AND nationality = '中國'
ORDER BY title;
插入數據
INSERT INTO writers(writer_id, writer_name, sex, birthday, nationality)
VALUES (1007, '三毛', 'F', '1943-03-26', '中國');
插入數據,省略指定列名,但是要依賴列的順序
INSERT INTO writers VALUES (1008, '畢淑敏', 'F', '1952-10-10', '中國');
插入部分數據
INSERT INTO writers(writer_id, writer_name, sex, nationality)
VALUES (1009, '老子', 'M', '中國');
插入多個行
INSERT INTO writers(writer_id, writer_name, sex, birthday, nationality)
VALUES (1010, '大仲馬', 'M', '1802-07-24', '法國'),
          (1011, '小仲馬', 'M', '1824-07-27', '法國');
插入檢索出的數據
INSERT INTO writers_bak(writer_id, writer_name, sex, birthday, nationality)
SELECT writer_id, writer_name, sex, birthday, nationality FROM writers;
更新數據
UPDATE writers
SET writer_name = '亞歷山大·仲馬'
WHERE writer_name = '大仲馬';
刪除數據
DELETE FROM writers WHERE writer_id = 1000;
刪除所有行,但是沒有刪除表
DELETE FROM writers_bak;
創建視圖
CREATE VIEW writer_books AS
SELECT writer_name, title
FROM writers w, books b
WHERE w.writer_id = b.author_id
ORDER BY writer_id;
刪除視圖
DROP VIEW writer_books;
創建存儲過程
DELIMITER //
CREATE PROCEDURE book_avg_price()
BEGIN
	SELECT AVG(price) FROM books;
END;//
DELIMITER ;
調用存儲過程
CALL book_avg_price();
刪除存儲過程
DROP PROCEDURE book_avg_price;
存儲過程使用參數
MySQL支持IN(傳遞給存儲過程)、OUT(從存儲過程中傳出)、INOUT(對存儲過程傳入傳出)三種類型的參數。
DELIMITER //
CREATE PROCEDURE get_writer_book_num(IN wid INT, OUT writer_book_num INT)
BEGIN
<span style="white-space:pre">	</span>SELECT (SELECT COUNT(*) FROM books b WHERE b.author_id = w.writer_id) INTO writer_book_num
<span style="white-space:pre">	</span>FROM writers w
<span style="white-space:pre">	</span>WHERE w.writer_id = wid;
END;//
DELIMITER ;

CALL get_writer_book_num(1001, @writer_book_num);

SELECT @writer_book_num;
遊標
DELIMITER //
CREATE PROCEDURE writer_book_num()
BEGIN
	DECLARE wid INT;
	DECLARE done INT DEFAULT 0;

	-- 聲明遊標
	DECLARE wid_cur CURSOR
	FOR
	SELECT writer_id FROM writers;

	-- 當遊標到達尾部時,mysql自動設置done = 1
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

	-- 打開遊標
	OPEN wid_cur;

	REPEAT
		-- 使用遊標
		FETCH wid_cur INTO wid;
		CALL get_writer_book_num(wid, @writer_book_num);
		SELECT wid, @writer_book_num;
	UNTIL done END REPEAT;

	-- 關閉遊標
	CLOSE wid_cur;
	
END;//
DELIMITER ;

CALL writer_book_num();

創建觸發器

delimiter //
CREATE TRIGGER trg_writers_insert
AFTER INSERT ON writers
FOR EACH ROW
BEGIN
	INSERT INTO writers_bak
		SELECT * FROM writers w WHERE w.writer_id = NEW.writer_id;
END;//
delimiter 
刪除觸發器
DROP TRIGGER IF EXISTS trg_writers_insert;
開啓事務
START TRANSACTION;
提交事務
COMMIT;
回滾事務
ROLLBACK;
默認的MySQL行爲是自動提交所有更改,可以修改這個設置
SET autocommit = 0;
創建保留點(事務處理塊中的佔位符)
SAVEPOINT point;
回退到保留點
ROLLBACK TO point;
創建用戶並指定口令
CREATE USER huey IDENTIFIED BY 'hueypass';
重命名用戶賬號
RENAME USER huey TO huey2672;
刪除用戶賬號
DROP USER huey;
查看用戶權限
SHOW GRANTS FOR huey;
賦予用戶權限
GRANT SELECT ON dream.* TO huey;

撤銷用戶權限
REVOKE SELECT ON dream.* FROM huey;
修改用戶口令
SET PASSWORD FOR huey = PASSWORD('huey');
修改自己的口令
SET PASSWORD = PASSWORD('root');
MySQL中的ENUM類型:
CREATE TABLE tmp_table(  
    season ENUM('Spring', 'Summer', 'Autumn', 'Winter')  
);  
INSERT INTO tmp_table VALUES('Spring');  
INSERT INTO tmp_table VALUES('summer');  
INSERT INTO tmp_table VALUES(1);  
INSERT INTO tmp_table VALUES(2);  
INSERT INTO tmp_table VALUES(3);  
INSERT INTO tmp_table VALUES(4);  
INSERT INTO tmp_table VALUES(NULL);  
SELECT * FROM tmp_table;
MySQL中的SET類型:
CREATE TABLE tmp_table(  
    season SET('Spring', 'Summer', 'Autumn', 'Winter')  
);  
INSERT INTO tmp_table values('Spring,Autumn,Winter');  
INSERT INTO tmp_table values('summer,WINTER');  
INSERT INTO tmp_table values(1);  
SELECT * FROM tmp_table; 







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