Mysql 8.0 第3章 簡單教程 (翻譯+理解)
教程
官方第三章文件 點我。
由於第3章都是一些操作性的例項,這裡就提取一下重點內容。
3.1 從伺服器連線和斷開
(1)連線: 指定 主機(-h),連線使用者(-u),密碼(-p)
shell> mysql - h host -u user -p
Enter password: ********
(2)斷開:
成功連線後,您可以通過在提示符mysql>
後鍵入QUIT
(或\q
)來隨時斷開連線:
mysql> QUIT
Bye
在Unix上,您也可以通過按Control + D
斷開連線。
3.2 輸入查詢
這是一個簡單的查詢,要求伺服器告訴您它的版本號和當前日期。
mysql> SELECT VERSION(), CURRENT_DATE;
+-----------+--------------+
| VERSION() | CURRENT_DATE |
+-----------+--------------+
| 5.8.0-m17 | 2015-12-21 |
+-----------+--------------+
1 row in set (0.02 sec)
mysql>
1.查詢語句以分號結尾,有些不用比如QUIT
2.輸出結果是表格形式,頭行顯示列名(你可以使用 as+別名 指定列名或用預設的)
3.輸出結果還顯示一個粗略的時間,表示查詢執行了多久,這個時間是系統時間(wall clock time
)而不是CPU時間
4.關鍵字不區分大小寫,如 sElect
等同於sELECt
mysql> SeLeCt vErSiOn(), current_DATE;
5.select 後面接算數表示式可以做個計算器 select 1+2
6.一行可以寫多個語句,用分號分隔開就行
mysql> SELECT VERSION(); SELECT NOW();
7.一條語句太長可以多行,用分號分結尾就行
mysql> SELECT
-> USER()
-> ,
-> CURRENT_DATE;
8.臨時取消語句:輸入\c
9. -> 等你輸入 '> "> `> /*> 這4個等你輸入相應的閉合字元
mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
'>
10.字串可以使用單引號或雙引號來包裹
3.3 建立和使用資料庫
後面的查詢例子都用了一個官方提供的寵物資料庫,先下載。
1.顯示所有資料庫: SHOW DATABASES;
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql |
| test |
| tmp |
+----------+
2.使用某個資料庫 USE dbname
;
mysql> USE test
Database changed
3.管理員使用者或root賦予使用者('your_mysql_name'@'your_client_host'
)某一資料庫(dbname
)的所有許可權
GRANT ALL ON dbname.* TO 'your_mysql_name'@'your_client_host';
3.3.1 建立和選擇資料庫
1.建立資料庫,create database dbname
:
linux機器上庫名區分大小寫,所以建議建立 小寫的 庫名,表名,列名。
mysql> CREATE DATABASE menagerie;
2.連線資料庫提供密碼的兩種方式
a. 使用-p
, p後留空白,代表在下一行輸入密碼。
shell> mysql -h host -p -u user
Enter password: ********
b. 使用-ppassword
,p後直接跟密碼。
shell> mysql -h host -u user -ppassword
3.3.2 建立表
1.顯示當前資料庫內的表 show tables;
2.建立一個寵物pet表和event表
CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
CREATE TABLE event (name VARCHAR(20), date DATE,type VARCHAR(15), remark VARCHAR(255));
3.VARCHAR
型別可以指定列的長度,可選1~65535
4.檢查建立pet表的語法 describe pet;
或者desc pet;
mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name | varchar(20) | YES | | NULL | |
| owner | varchar(20) | YES | | NULL | |
| species | varchar(20) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| birth | date | YES | | NULL | |
| death | date | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
3.3.3 將資料載入到表中
1.可以使用LOAD DATA
或Insert into
兩種方法載入資料
2.如果你的資料在txt中,可以用tab來區分每一個列,使用\N
表示當前資料為空,使用'YYYY-MM-DD'
表示一個日期。
下面是pet.txt
中的資料:
3.1 使用LOAD DATA
匯入資料
LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;
windows提供檔案路徑使用雙反斜線C:\\windows\\pet.txt
注意:如果出現錯誤The used command is not allowed with this MySQL version
,那是因為系統變數local_infile
沒有開啟。
解決方案:
(1)停止mysql服務,修改配置檔案,在[mysqld]
部分增加
[mysqld]
local_infile = ON
(2)開啟mysql服務,使用mysql客戶端連線的時候提供引數--local-infile=1
。
shell> mysql -uxxx -P 34567 -p menagerie --local-infile=1
(3)執行LOAD DATA
,插入成功。
(4)如果你的匯入還有問題,請參閱 Section 6.1.6, “Security Issues with LOAD DATA LOCAL“
3.2 使用INSERT INTO
一次插入一條
INSERT INTO pet VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
3.3.4 從表中檢索資訊
0.檢索pet表資料
select * from pet;
SELECT * FROM pet WHERE birth >= '1998-1-1';
1.修改某條資料
UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';
字串比較時通常對大小些不敏感,例如 BOWser
2.AND
和OR
可以混用,但AND比OR具有更高的優先順序.如果你使用兩個操作符,使用圓括號指明如何對條件進行分組
SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm') OR (species = 'dog' AND sex = 'f');
3.對選擇的列去重
SELECT DISTINCT owner FROM pet;
增加關鍵字DISTINCT檢索出每個唯一的輸出記錄,DISTINCT後面可以接多列進行最少輸出
4.對結果進行排序
SELECT name,birth FROM pet order by [binary] birth [ASC|DESC];
預設排序是升序(ASC) ,且大小寫不敏感,如果想敏感可以在列名前增加binary
,如果降序可以用DESC;可以對每個列都進行排序 (有種先分組再在組內排序的意思)
mysql> SELECT name, species, birth FROM pet
-> ORDER BY species, birth DESC;
+----------+---------+------------+
| name | species | birth |
+----------+---------+------------+
| Chirpy | bird | 1998-09-11 |
| Whistler | bird | 1997-12-09 |
| Claws | cat | 1994-03-17 |
| Fluffy | cat | 1993-02-04 |
| Fang | dog | 1990-08-27 |
| Bowser | dog | 1989-08-31 |
| Buffy | dog | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim | snake | 1996-04-29 |
+----------+---------+------------+
5.日期計算
(1)年齡的兩種計算方式
- 使用內建的
TIMESTAMPDIFF
方法(簡單)
SELECT name, birth, CURDATE(),TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age FROM pet;
- 先算年,然後日期比較看是否要-1
SELECT name,birth,(YEAR(CURDATE())-YEAR(birth))- (RIGHT(CURDATE(),5)<RIGHT(birth,5)) AS age FROM pet;
(2)下個月過生日計算的兩種方法:
- 使用內建
DATE_ADD
函式
SELECT name, birth FROM pet WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));
- 使用內建
MOD
函式
SELECT name, birth FROM pet WHERE MONTH(birth) = MOD(MONTH(CURDATE()),12)+1
6.空值NULL
使用colnum IS NOT NULL
而非colnum != NULL來進行比較,因為NULL是特殊的值,不能使用普通比較符來比較;
mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
-> 0,1
NULL的算數比較結果都是NULL ,
mysql> SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1 <> NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
| NULL | NULL | NULL | NULL |
+----------+-----------+----------+----------+
In MySQL,0 or NULL means false and anything else means true
在GROUP BY
中,兩個NULL值視為相同
使用ORDER BY排序時,如果有NULL值,則它出現在最前面;DESC的時候,出現在最後面。
mysql> select sex from pet order by sex asc;
7.模式匹配
模式匹配允許你使用 _
匹配任何單個字元(包含0個字元)
而%
匹配任意數目字元(包括0個字元)
模式匹配預設是忽略大小寫的(BINARY 來強制敏感)
使用LIKE
或 NOT LIKE
(或者使用 REGEXP
和NOT REGEXP
)
mysql> SELECT * FROM pet WHERE name LIKE '%w%';
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b');
更多請見 Section 12.5.2, “Regular Expressions”.
8.計數
(1)瞭解每位業主擁有多少寵物
SELECT owner, COUNT(*) FROM pet GROUP BY owner;
(2)group by 用在 where 之後
(3)用在groupb by 語句中,如果你使用了某一列(name),和一個聚合函式列,你需要指定group by name
,否則在ONLY_FULL_GROUP_BY
這種sql模式下會報錯,例如:
mysql> SET sql_mode = 'ONLY_FULL_GROUP_BY';
mysql> SELECT owner, COUNT(*) FROM pet;
ERROR 1140 (42000): In aggregated query without GROUP BY, expression
#1 of SELECT list contains nonaggregated column 'menager
修改為下面的語句,才會正常:
SELECT owner, COUNT(*) FROM pet group by owner;
9.連線多表
- Inner join 連線兩張表 (比如,查詢寵物生寶寶時候的年齡和具體細節
)
SELECT pet.name, TIMESTAMPDIFF(YEAR,birth,date) AS age,remark
FROM pet INNER JOIN event ON pet.name = event.name
WHERE event.type = 'litter';
- 連線自身
mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species FROM pet AS p1, pet AS p2
WHERE p1.species = p2.species AND p1.sex = 'f' AND p2.sex = 'm';
+--------+------+--------+------+---------+
| name | sex | name | sex | species |
+--------+------+--------+------+---------+
| Fluffy | f | Claws | m | cat |
| Buffy | f | Fang | m | dog |
| Buffy | f | Bowser | m | dog |
+--------+------+--------+------+---------+
10.如果表有索引,SHOW INDEX FROM tbl_name
生成有關索引的資訊。
3.5 在批處理模式下使用mysql
(1)windows下:
mysql -e "source C:\\Users\\eve\\Desktop\\batch.txt" [>file| more] [-t -vvv]
(2)linux 下:
msyql < batch.txt
cron模式下不許使用互動,最好使用批處理檔案
3.6. 常用查詢的例子
1.例項表:
CREATE TABLE shop (article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,dealer CHAR(20) DEFAULT '' NOT NULL,price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),(3,'C',1.69),(3,'D',1.25),(4,'D',19.95);
(1)求某列中的最大值
SELECT MAX(article) AS article FROM shop;
(2)求擁有某列最大值的行
例如:找出最貴物品(article)的價格(price),經銷商(dealer),有三種解決方案
- a 子查詢
SELECT article, dealer, price
FROM shop
WHERE price=(SELECT MAX(price) FROM shop);
- b 左連線 或右連線
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price < s2.price
WHERE s2.article IS NULL;
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
RIGHTJOIN shop s2 ON s1.price > s2.price
WHERE s1.article IS NULL;
- c
order by
+limit
SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1;
如果有幾個最昂貴的文章,每個價格為19.95,LIMIT解決方案只顯示其中一個。
(3)求每組擁有的最大列值
例如:找到每種物品的最高價格
select article,max(price) from shop group by article;
(4)求每組內擁有某列最大值的行
例如:對每項物品,找出最貴价格的物品的經銷商。
- 通過子查詢(這是一個相關子查詢,效率可能低下)
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
FROM shop s2
WHERE s1.article = s2.article)
ORDER BY article;
- 在FROM內使用非相關子查詢
SELECT s1.article, dealer, s1.price
FROM shop s1
JOIN (
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article) AS s2
ON s1.article = s2.article AND s1.price = s2.price
ORDER BY article;
- 左外連線
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.article = s2.article AND s1.price < s2.price
WHERE s2.article IS NULL
ORDER BY s1.article;
更多關於連線的使用,請參考 第13.2.10.2節“JOIN語法”
- 帶視窗函式的公用表表達式
WITH s1 AS (
SELECT article, dealer, price,
RANK() OVER (PARTITION BY article
ORDER BY price DESC
) AS `Rank`
FROM shop
)
SELECT article, dealer, price
FROM s1
WHERE `Rank` = 1
ORDER BY article;
2.使用使用者變數
SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
3.確定每個月的訪問天數
3.1 例項表
CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL,
day INT(2) UNSIGNED ZEROFILL);
INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),
(2000,2,23),(2000,2,23);
SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1 GROUP BY year,month
4.對於MyISAM表,在一張表的第二列定義列含有 AUTO_INCREMENT屬性,並將一二列做成多列索引,可以達成一種資料分組的情況,例如:
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird'