SQL的學習之路,主要參考資料是:
操作使用的數據庫為Access及MySQL。
數據采用的是SQL必知必會中的數據(最下方可以下載數據)。其有5個表,表的關系如下:

1 # 這里補充下,MySQL創建該數據庫(2017.5.17),復制到MySQL創建執行創建即可(數據來源於《SQL必知必會》); 2 3 -- ---------------------- 4 -- Create Customers table 5 -- ---------------------- 6 CREATE TABLE Customers 7 ( 8 cust_id char(10) NOT NULL , 9 cust_name char(50) NOT NULL , 10 cust_address char(50) NULL , 11 cust_city char(50) NULL , 12 cust_state char(5) NULL , 13 cust_zip char(10) NULL , 14 cust_country char(50) NULL , 15 cust_contact char(50) NULL , 16 cust_email char(255) NULL 17 ); 18 19 -- ----------------------- 20 -- Create OrderItems table 21 -- ----------------------- 22 CREATE TABLE OrderItems 23 ( 24 order_num int NOT NULL , 25 order_item int NOT NULL , 26 prod_id char(10) NOT NULL , 27 quantity int NOT NULL , 28 item_price decimal(8,2) NOT NULL 29 ); 30 31 32 -- ------------------- 33 -- Create Orders table 34 -- ------------------- 35 CREATE TABLE Orders 36 ( 37 order_num int NOT NULL , 38 order_date datetime NOT NULL , 39 cust_id char(10) NOT NULL 40 ); 41 42 -- --------------------- 43 -- Create Products table 44 -- --------------------- 45 CREATE TABLE Products 46 ( 47 prod_id char(10) NOT NULL , 48 vend_id char(10) NOT NULL , 49 prod_name char(255) NOT NULL , 50 prod_price decimal(8,2) NOT NULL , 51 prod_desc text NULL 52 ); 53 54 -- -------------------- 55 -- Create Vendors table 56 -- -------------------- 57 CREATE TABLE Vendors 58 ( 59 vend_id char(10) NOT NULL , 60 vend_name char(50) NOT NULL , 61 vend_address char(50) NULL , 62 vend_city char(50) NULL , 63 vend_state char(5) NULL , 64 vend_zip char(10) NULL , 65 vend_country char(50) NULL 66 ); 67 68 69 -- ------------------- 70 -- Define primary keys 71 -- ------------------- 72 ALTER TABLE Customers ADD PRIMARY KEY (cust_id); 73 ALTER TABLE OrderItems ADD PRIMARY KEY (order_num, order_item); 74 ALTER TABLE Orders ADD PRIMARY KEY (order_num); 75 ALTER TABLE Products ADD PRIMARY KEY (prod_id); 76 ALTER TABLE Vendors ADD PRIMARY KEY (vend_id); 77 78 79 -- ------------------- 80 -- Define foreign keys 81 -- ------------------- 82 ALTER TABLE OrderItems ADD CONSTRAINT FK_OrderItems_Orders FOREIGN KEY (order_num) REFERENCES Orders (order_num); 83 ALTER TABLE OrderItems ADD CONSTRAINT FK_OrderItems_Products FOREIGN KEY (prod_id) REFERENCES Products (prod_id); 84 ALTER TABLE Orders ADD CONSTRAINT FK_Orders_Customers FOREIGN KEY (cust_id) REFERENCES Customers (cust_id); 85 ALTER TABLE Products ADD CONSTRAINT FK_Products_Vendors FOREIGN KEY (vend_id) REFERENCES Vendors (vend_id); 86 87 # 插入數據 88 -- ------------------------ 89 -- Populate Customers table 90 -- ------------------------ 91 INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) 92 VALUES('1000000001', 'Village Toys', '200 Maple Lane', 'Detroit', 'MI', '44444', 'USA', 'John Smith', 'sales@villagetoys.com'); 93 INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact) 94 VALUES('1000000002', 'Kids Place', '333 South Lake Drive', 'Columbus', 'OH', '43333', 'USA', 'Michelle Green'); 95 INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) 96 VALUES('1000000003', 'Fun4All', '1 Sunny Place', 'Muncie', 'IN', '42222', 'USA', 'Jim Jones', 'jjones@fun4all.com'); 97 INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) 98 VALUES('1000000004', 'Fun4All', '829 Riverside Drive', 'Phoenix', 'AZ', '88888', 'USA', 'Denise L. Stephens', 'dstephens@fun4all.com'); 99 INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact) 100 VALUES('1000000005', 'The Toy Store', '4545 53rd Street', 'Chicago', 'IL', '54545', 'USA', 'Kim Howard'); 101 102 -- ---------------------- 103 -- Populate Vendors table 104 -- ---------------------- 105 INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country) 106 VALUES('BRS01','Bears R Us','123 Main Street','Bear Town','MI','44444', 'USA'); 107 INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country) 108 VALUES('BRE02','Bear Emporium','500 Park Street','Anytown','OH','44333', 'USA'); 109 INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country) 110 VALUES('DLL01','Doll House Inc.','555 High Street','Dollsville','CA','99999', 'USA'); 111 INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country) 112 VALUES('FRB01','Furball Inc.','1000 5th Avenue','New York','NY','11111', 'USA'); 113 INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country) 114 VALUES('FNG01','Fun and Games','42 Galaxy Road','London', NULL,'N16 6PS', 'England'); 115 INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country) 116 VALUES('JTS01','Jouets et ours','1 Rue Amusement','Paris', NULL,'45678', 'France'); 117 118 -- ----------------------- 119 -- Populate Products table 120 -- ----------------------- 121 INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc) 122 VALUES('BR01', 'BRS01', '8 inch teddy bear', 5.99, '8 inch teddy bear, comes with cap and jacket'); 123 INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc) 124 VALUES('BR02', 'BRS01', '12 inch teddy bear', 8.99, '12 inch teddy bear, comes with cap and jacket'); 125 INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc) 126 VALUES('BR03', 'BRS01', '18 inch teddy bear', 11.99, '18 inch teddy bear, comes with cap and jacket'); 127 INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc) 128 VALUES('BNBG01', 'DLL01', 'Fish bean bag toy', 3.49, 'Fish bean bag toy, complete with bean bag worms with which to feed it'); 129 INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc) 130 VALUES('BNBG02', 'DLL01', 'Bird bean bag toy', 3.49, 'Bird bean bag toy, eggs are not included'); 131 INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc) 132 VALUES('BNBG03', 'DLL01', 'Rabbit bean bag toy', 3.49, 'Rabbit bean bag toy, comes with bean bag carrots'); 133 INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc) 134 VALUES('RGAN01', 'DLL01', 'Raggedy Ann', 4.99, '18 inch Raggedy Ann doll'); 135 INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc) 136 VALUES('RYL01', 'FNG01', 'King doll', 9.49, '12 inch king doll with royal garments and crown'); 137 INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc) 138 VALUES('RYL02', 'FNG01', 'Queen doll', 9.49, '12 inch queen doll with royal garments and crown'); 139 140 -- --------------------- 141 -- Populate Orders table 142 -- --------------------- 143 INSERT INTO Orders(order_num, order_date, cust_id) 144 VALUES(20005, '2012-05-01', '1000000001'); 145 INSERT INTO Orders(order_num, order_date, cust_id) 146 VALUES(20006, '2012-01-12', '1000000003'); 147 INSERT INTO Orders(order_num, order_date, cust_id) 148 VALUES(20007, '2012-01-30', '1000000004'); 149 INSERT INTO Orders(order_num, order_date, cust_id) 150 VALUES(20008, '2012-02-03', '1000000005'); 151 INSERT INTO Orders(order_num, order_date, cust_id) 152 VALUES(20009, '2012-02-08', '1000000001'); 153 154 -- ------------------------- 155 -- Populate OrderItems table 156 -- ------------------------- 157 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 158 VALUES(20005, 1, 'BR01', 100, 5.49); 159 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 160 VALUES(20005, 2, 'BR03', 100, 10.99); 161 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 162 VALUES(20006, 1, 'BR01', 20, 5.99); 163 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 164 VALUES(20006, 2, 'BR02', 10, 8.99); 165 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 166 VALUES(20006, 3, 'BR03', 10, 11.99); 167 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 168 VALUES(20007, 1, 'BR03', 50, 11.49); 169 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 170 VALUES(20007, 2, 'BNBG01', 100, 2.99); 171 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 172 VALUES(20007, 3, 'BNBG02', 100, 2.99); 173 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 174 VALUES(20007, 4, 'BNBG03', 100, 2.99); 175 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 176 VALUES(20007, 5, 'RGAN01', 50, 4.49); 177 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 178 VALUES(20008, 1, 'RGAN01', 5, 4.99); 179 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 180 VALUES(20008, 2, 'BR03', 5, 11.99); 181 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 182 VALUES(20008, 3, 'BNBG01', 10, 3.49); 183 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 184 VALUES(20008, 4, 'BNBG02', 10, 3.49); 185 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 186 VALUES(20008, 5, 'BNBG03', 10, 3.49); 187 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 188 VALUES(20009, 1, 'BNBG01', 250, 2.49); 189 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 190 VALUES(20009, 2, 'BNBG02', 250, 2.49); 191 INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price) 192 VALUES(20009, 3, 'BNBG03', 250, 2.49);
看不清的圖片:右擊新標簽頁打開即可。
1.SQL基礎
2.檢索數據
#SQL對大小寫不敏感 #檢索單個列 SELECT prod_name FROM products; #檢索多個列 SELECT prod_name,prod_id,prod_price FROM products; #檢索多個列 SELECT * FROM products; #檢索不同的值 SELECT DISTINCT vend_id FROM products; #限制結果,需要好好理解 SELECT prod_name FROM products LIMIT 5; SELECT prod_name FROM products LIMIT 4 OFFSET 5;#4是檢索的行數,5是從那兒開始 SELECT prod_name FROM products LIMIT 5,2;#逗號前,從哪兒開始,逗號后,檢索行數
3.排序檢索數據
#排序檢索 SELECT prod_name FROM products ORDER BY prod_name; #多個列 SELECT prod_id,prod_price,prod_name FROM products ORDER BY prod_price,prod_name; #按照列的相對位置 SELECT prod_id,prod_price,prod_name FROM products ORDER BY 2,3; #混合使用 SELECT prod_id,prod_price,prod_name FROM products ORDER BY 2,vend_id; #降序 SELECT prod_id,prod_price,prod_name FROM products ORDER BY prod_price DESC; #多個列降序 SELECT prod_id,prod_price,prod_name FROM products ORDER BY prod_price DESC,prod_name DESC;
4.過濾數據
#where子句過濾數據 SELECT prod_name,prod_price FROM products WHERE prod_price = 3.49; SELECT prod_name,prod_price FROM products WHERE prod_price > 3.49 ORDER BY prod_price DESC; #不匹配檢查 SELECT vend_id,prod_name FROM products WHERE vend_id != 'DLL01'; #范圍值 SELECT prod_name,prod_price FROM products WHERE prod_price BETWEEN 5 AND 10; #空值檢查 SELECT cust_name FROM customers WHERE cust_email IS NULL;
5.高級過濾
#組合where子句 SELECT prod_id,prod_price,prod_name FROM products WHERE vend_id = "DLL01" AND prod_price <= 4 ORDER BY prod_name; SELECT prod_name,prod_price FROM products WHERE vend_id = "DLL01" OR vend_id = "BRS01"; #優先級 SELECT prod_name,prod_price FROM products WHERE vend_id = "DLL01" OR vend_id = "BRS01" AND prod_price >=10; SELECT prod_name,prod_price FROM products WHERE (vend_id = "DLL01" OR vend_id = "BRS01") AND prod_price >=10; #in SELECT prod_name,prod_price FROM products WHERE vend_id IN ('DLL01','BRS01') ORDER BY prod_name; SELECT prod_name,prod_price FROM products WHERE vend_id = 'DLL01' OR vend_id = 'BRS01'; SELECT prod_name,prod_price FROM products WHERE vend_id IN ('DLL01','BRS01') AND prod_price >= 10; #not SELECT prod_name,prod_price FROM products WHERE NOT vend_id ="DLL01" ORDER BY prod_name; SELECT prod_name,prod_price FROM products WHERE vend_id <> 'DLL01' ORDER BY prod_name; SELECT prod_name,prod_price FROM products WHERE NOT vend_id IN ('DLL01','BRS01') AND prod_price >= 5;
6.通配符過濾
#不區分大小寫,但是區分空格 SELECT prod_id,prod_name FROM products WHERE prod_name LIKE 'Fish%';
SELECT prod_id,prod_name FROM products WHERE prod_name LIKE "%bean bag%";
SELECT prod_id,prod_name FROM products WHERE prod_name LIKE 'F%y';
SELECT cust_email FROM customers WHERE cust_email LIKE '%@fun4all.com'; #%可以匹配空格,但是不能匹配NULL #x下划線 SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '__ inch teddy bear'; SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '% inch teddy bear';
7.創建計算字段
8.函數特性
9.函數
10.匯總數據
11.分組數據
12.子查詢
這里說白了就是select語句嵌套,如select * from (select cust_name from customers)
13.聯結
所謂的表的聯結,其實就是將幾個表的信息綜合到一起,進而成為一個表。而這種綜合其實是通過這幾個表相同的主鍵,或者列,來進行選擇。
14.高級聯結
如果3個以上的表,那怎樣聯結?
1. 3個
1 use test; 2 select cust_name,cust_contact 3 from (customers 4 inner join orders 5 on customers.cust_id = orders.cust_id) 6 inner join orderitems 7 on orderitems.order_num = orders.order_num;
語法可以概括為:
FROM (表1 INNER JOIN 表2 ON 表1.字段號=表2.字段號) INNER JOIN 表3 ON 表1.字段號=表3.字段號
2. 同理,4個表可以概括為:
FROM ((表1 INNER JOIN 表2 ON 表1.字段號=表2.字段號) INNER JOIN 表3 ON 表1.字段號=表3.字段號) INNER JOIN 表4 ON Member.字段號=表4.字段號
15.組合查詢
關於規則中列順序,前后必須一致。否則會出現如下情況:
1 use test; 2 select cust_name ,cust_email,cust_contact 3 from customers 4 where cust_state in ('IL','IN','MI') 5 union all 6 select cust_name,cust_contact,cust_email 7 from customers 8 where cust_name = 'Fun4All'
返回結果為:
cust_name | cust_email | cust_contact |
Village Toys | sales@villagetoys.com | John Smith |
Fun4All | jjones@fun4all.com | Jim Jones |
The Toy Store | Kim Howard | |
Fun4All | Jim Jones | jjones@fun4all.com |
Fun4All | Denise L. Stephens | dstephens@fun4all.com |
列的順序一致,才會返回正確結果
1 use test; 2 select cust_name ,cust_email,cust_contact 3 from customers 4 where cust_state in ('IL','IN','MI') 5 union all 6 select cust_name,cust_email,cust_contact 7 from customers 8 where cust_name = 'Fun4All'
結果:
cust_name | cust_email | cust_contact |
Village Toys | sales@villagetoys.com | John Smith |
Fun4All | jjones@fun4all.com | Jim Jones |
The Toy Store | Kim Howard | |
Fun4All | jjones@fun4all.com | Jim Jones |
Fun4All | dstephens@fun4all.com | Denise L. Stephens |
16.插入數據
INSERT SELECT:
它可以將SELCET語句結果插入表中,在某種意義上可以完成表的復制。
如:
1 USE test;#使用數據庫test 2 CREATE TABLE CustNew 3 ( 4 cust_id char(10) NOT NULL , 5 cust_name char(50) NOT NULL , 6 cust_address char(50) NULL , 7 cust_city char(50) NULL , 8 cust_state char(5) NULL , 9 cust_zip char(10) NULL , 10 cust_country char(50) NULL , 11 cust_contact char(50) NULL , 12 cust_email char(255) NULL 13 );#創新新表 14 INSERT INTO CustNew 15 ( 16 cust_id, 17 cust_name, 18 cust_address, 19 cust_city, 20 cust_state, 21 cust_zip, 22 cust_country, 23 cust_contact, 24 cust_email 25 ) 26 SELECT 27 cust_id, 28 cust_name, 29 cust_address, 30 cust_city, 31 cust_state, 32 cust_zip, 33 cust_country, 34 cust_contact, 35 cust_email 36 FROM customers;#將customers表的數據插入新表alter 37 SELECT * FROM CustNew;
返回結果如下:
而如果反過來用,大概就是:
1 insert into 2 customers 3 (列1,列2,......) 4 select 5 列1,列2,..... 6 from custnew
即可完成將表custnew中的數據全部插入customers,這也完成了一條insert插入多條數據。
通常,一條INSERT 語句,只能插入一行數據,要插入多行,就必須執行多個INSERT,但是, INSERT SELECT 是個例外。
以上方法的復制,實際上是重新在數據庫中創建了一個新表。
SELECT INTO:
這種方法,可以在SQL語句運行中創建一個表,並將一個表復制到這個全新的表。
我們可以在實驗新的SQL語句前,用其進行復制,這樣就不影響到實際數據。
如:
USE test;#使用數據庫 CREATE TABLE Cucopy as SELECT * FROM customers;#復制 SELECT * FROM Cucopy;
返回結果,與上表一致。
17.更新和刪除
18.創建和操縱表
這里中點說一下創建表時,指定默認值的問題。一般來說,創建表時,我們需要指定列的數據類型、是否NULL列。關於NULL值具體說明請看下圖。
默認值要是用的好,可以省卻我們很多時間。
因其經常用於指定默認日期,這里以日期為例。
首先,在MySQL中內建的日期函數:
函數 | 描述 |
---|---|
NOW() | 返回當前的日期和時間 |
CURDATE() | 返回當前的日期 |
CURTIME() | 返回當前的時間 |
DATE() | 提取日期或日期/時間表達式的日期部分 |
EXTRACT() | 返回日期/時間按的單獨部分 |
DATE_ADD() | 給日期添加指定的時間間隔 |
DATE_SUB() | 從日期減去指定的時間間隔 |
DATEDIFF() | 返回兩個日期之間的天數 |
DATE_FORMAT() | 用不同的格式顯示日期/時間 |
創建數據庫t2,插入表。如下:
CREATE DATABASE t2; USE t2; CREATE TABLE test (id int(5) NOT NULL, noedate timestamp NOT NULL DEFAULT current_timestamp() );
調用如下:
USE t2; INSERT INTO test(id) values(1); SELET * FROM test;
返回結果:
id | nowdate |
1 | 2017-05-08 22:09:45 |
以下SQL不合法:
--time_d time NOT NULL DEFAULT CURTIME(), --date_e date NOT NULL DEFAULT CURDATE(), --datetime_f datetime NOT NULL DEFAULT NOW(),
DATETIME類型:NOW()函數以'YYYY-MM-DD HH:MM:SS'返回當前的日期時間,可以直接存到DATETIME字段中。不支持使用系統默認值。
DATE類型:CURDATE()以'YYYY-MM-DD'的格式返回今天的日期,可以直接存到DATE字段中。不支持使用系統默認值。
TIME類型:CURTIME()以'HH:MM:SS'的格式返回當前的時間,可以直接存到TIME字段中。不支持使用系統默認值。
常見錯誤:
CREATE TABLE dnt_forums ( aa int NOT NULL DEFAULT (''), bb date NOT NULL DEFAULT (getdate()), cc char(50) NOT NULL DEFAULT (null) );
aa 是 int 類型,默認值也得是整型,並且default后邊不要()括號 。
bb date類型不支持使用系統默認值,改成timestamp,能過now()取系統時間 。
cc 已經不允許為空(not null)所以不能默認為 null ,可以改成空字符串 。
修改:
CREATE TABLE dnt_forums( aa int NOT NULL DEFAULT 2, bb timestamp NOT NULL DEFAULT now(), cc char(50) NOT NULL DEFAULT '' );
這個日期問題,依然有很多不太明白的地方,以后學習過程碰到繼續解決。
主要參考:
重命名表:
RENAME TABLE cucopy1 TO hi;
刪除表:
DROP TABLE hi;