09.MySQL子查詢和鏈接

0準備工做:mysql

先爲劍表添加兩個屬性:屬性(attr)和類型(type)
mysql> ALTER TABLE sword ADD attr VARCHAR(4) NOT NULL;
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE sword ADD type VARCHAR(8) NOT NULL;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> SELECT*FROM sword; +----+--------+-------+------+-------+------+------+
| id | name | atk | hit | crit | attr | type | +----+--------+-------+------+-------+------+------+
|  1 | 黑風   | 10800 |  400 |   400 |      |      |
|  2 | 木藜   |  5400 |  200 |   200 |      |      |
|  3 | 荊戈   |  8020 | 1000 |    10 |      |      |
|  4 | 痕兮   |  8998 |  800 |   999 |      |      |
|  5 | 逐暮   |   100 | 1000 | 10000 |      |      |
|  6 | 風躍   |  9020 |   10 |    10 |      |      |
|  8 | 洛神   | 20020 |    1 |    10 |      |      |
| 9 | 隱鋒 | 8020 | 2000 | 10 | | | +----+--------+-------+------+-------+------+------+
8 rows in set (0.00 sec)
修改數據:(爲屬性添加值)
mysql> UPDATE sword SET attr='木',type='神界' WHERE name='黑風';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

mysql> UPDATE sword SET attr='木',type='人界' WHERE name='木藜';
Query OK, 0 rows affected (0.01 sec)
Rows matched: 1  Changed: 0  Warnings: 0

mysql> UPDATE sword SET attr='金',type='魔界' WHERE name='荊戈';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> UPDATE sword SET attr='水',type='道界' WHERE name='痕兮';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> UPDATE sword SET attr='火',type='鬼界' WHERE name='逐暮';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> UPDATE sword SET attr='木',type='仙界' WHERE name='風躍';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> UPDATE sword SET attr='金',type='神界' WHERE name='洛神';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> UPDATE sword SET attr='土',type='人界' WHERE name='隱鋒';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT*FROM sword;
+----+--------+-------+------+-------+------+--------+
| id | name   | atk   | hit  | crit  | attr | type   |
+----+--------+-------+------+-------+------+--------+
|  1 | 黑風   | 10800 |  400 |   400 || 神界   |
|  2 | 木藜   |  5400 |  200 |   200 || 人界   |
|  3 | 荊戈   |  8020 | 1000 |    10 || 魔界   |
|  4 | 痕兮   |  8998 |  800 |   999 || 道界   |
|  5 | 逐暮   |   100 | 1000 | 10000 || 鬼界   |
|  6 | 風躍   |  9020 |   10 |    10 || 仙界   |
|  8 | 洛神   | 20020 |    1 |    10 || 神界   |
|  9 | 隱鋒   |  8020 | 2000 |    10 || 人界   |
+----+--------+-------+------+-------+------+--------+
8 rows in set (0.00 sec)
8 rows in set (0.00 sec)

子查詢

出如今其餘SQL語句內的SELECT語句
子查詢必須在()內
增刪改查均可以進行子查詢
返回:標量,行,列或子查詢
1.比較運算符的子查詢(=、>、<、>=、<=、<>、!=、<=>)
  • 計算平均攻擊力(四捨五入2位)
mysql> SELECT ROUND(AVG(atk),2) AS '平均攻擊力' FROM sword; +-----------------+
| 平均攻擊力 | +-----------------+
| 8797.25 | +-----------------+
1 row
  • 普通查詢:全部攻擊力格大於平均攻擊力的劍,並降序排序
mysql> SELECT * FROM sword WHERE atk > 5636.36 ORDER BY atk DESC; +----+--------+-------+------+------+------+--------+
| id | name | atk | hit | crit | attr | type | +----+--------+-------+------+------+------+--------+
|  8 | 洛神   | 20020 |    1 |   10 | 金   | 神界   |
|  1 | 黑風   | 10800 |  400 |  400 | 木   | 神界   |
|  6 | 風躍   |  9020 |   10 |   10 | 木   | 仙界   |
|  4 | 痕兮   |  8998 |  800 |  999 | 水   | 道界   |
|  3 | 荊戈   |  8020 | 1000 |   10 | 金   | 魔界   |
| 9 | 隱鋒 | 8020 | 2000 | 10 | 土 | 人界 | +----+--------+-------+------+------+------+--------+
6 rows in set (0.00 sec)
  • 使用子查詢(也就是將上面兩步簡化爲一步)
mysql> SELECT * FROM sword WHERE atk >
 -> (SELECT ROUND(AVG(atk),2) AS '平均攻擊力' FROM sword)
 -> ORDER BY atk DESC; +----+--------+-------+-----+------+------+--------+
| id | name | atk | hit | crit | attr | type | +----+--------+-------+-----+------+------+--------+
|  8 | 洛神   | 20020 |   1 |   10 | 金   | 神界   |
|  1 | 黑風   | 10800 | 400 |  400 | 木   | 神界   |
|  6 | 風躍   |  9020 |  10 |   10 | 木   | 仙界   |
| 4 | 痕兮 | 8998 | 800 | 999 | 水 | 道界 | +----+--------+-------+-----+------+------+--------+
4 rows in set (0.00 sec)
2.ANY、SOME、ALL、IN
ANY     知足一條便可查詢到
SOME    同ANY
ALL     知足全部可查詢到
IN      等價於  = ANY 或 = SOME

查詢類型爲人界的劍攻擊力sql

mysql> SELECT atk FROM sword WHERE type = '人界'; +------+
| atk | +------+
| 5400 |
| 8020 | +------+
2 rows in set (0.00 sec)
2 rows in set (0.00 sec)
查詢攻擊力大於(任意一個:ANY)」人族」的劍名稱,並降序排列

雖然荊戈的攻擊力不大於8020,但大於5400,知足一個就能查詢到spa

mysql> SELECT id,name,atk FROM sword WHERE atk >
 -> ANY(SELECT atk FROM sword WHERE type = '人界')
 -> ORDER BY atk DESC; +----+--------+-------+
| id | name | atk | +----+--------+-------+
|  8 | 洛神   | 20020 |
|  1 | 黑風   | 10800 |
|  6 | 風躍   |  9020 |
|  4 | 痕兮   |  8998 |
|  3 | 荊戈   |  8020 |
| 9 | 隱鋒 | 8020 | +----+--------+-------+
6 rows in set (0.00 sec)
查詢攻擊力大於(全部:ALL)」人族」的劍名稱,並降序排列

雖然荊戈的攻擊力大於5400,但不大於8020,因此查不到code

mysql> SELECT id,name,atk FROM sword WHERE atk >
 -> ALL(SELECT atk FROM sword WHERE type = '人界')
 -> ORDER BY atk DESC; +----+--------+-------+
| id | name | atk | +----+--------+-------+
|  8 | 洛神   | 20020 |
|  1 | 黑風   | 10800 |
|  6 | 風躍   |  9020 |
| 4 | 痕兮 | 8998 | +----+--------+-------+
4 rows in set (0.00 sec)
查詢任意攻擊力等於」人族」的劍名稱,並降序排列
mysql> SELECT id,name,atk FROM sword WHERE atk IN
 -> (SELECT atk FROM sword WHERE type = '人界')
 -> ORDER BY atk DESC; +----+--------+------+
| id | name | atk | +----+--------+------+
|  3 | 荊戈   | 8020 |
|  9 | 隱鋒   | 8020 |
| 2 | 木藜 | 5400 | +----+--------+------+
3 rows in set (0.00 sec)

建立類型分類表

  • 建表
mysql> CREATE TABLE IF NOT EXISTS sword_type(
    -> type_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,     -> type_name VARCHAR(8)     -> ); Query OK, 0 rows affected (0.04 sec)
  • 用分組查詢查看劍分類:
mysql> SELECT type FROM sword GROUP BY type; +--------+
| type | +--------+
| 人界   |
| 仙界   |
| 神界   |
| 道界   |
| 鬼界   |
| 魔界 | +--------+
6 rows in set (0.00 sec)

##### ☆☆☆☆☆將查詢的結果寫入另外一個數據表:
- 根據type的分組,經過sword的type字段,插入到sword_type表中的type_name字段排序

mysql> INSERT sword_type (type_name) SELECT type FROM sword GROUP BY type;
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT*FROM sword_type; +---------+-----------+
| type_id | type_name | +---------+-----------+
|       1 | 人界      |
|       2 | 仙界      |
|       3 | 神界      |
|       4 | 道界      |
|       5 | 鬼界      |
| 6 | 魔界 | +---------+-----------+
6 rows in set (0.00 sec)
☆☆☆☆☆

使用type_id更新sword中的數據ci

mysql>  UPDATE sword INNER JOIN sword_type -> ON type = type_name
 -> SET type = type_id ;
Query OK, 8 rows affected (0.00 sec)
Rows matched: 8  Changed: 8  Warnings: 0

mysql> SELECT*FROM sword; +----+--------+-------+------+-------+------+------+
| id | name | atk | hit | crit | attr | type | +----+--------+-------+------+-------+------+------+
|  1 | 黑風   | 10800 |  400 |   400 | 木   | 3    |
|  2 | 木藜   |  5400 |  200 |   200 | 木   | 1    |
|  3 | 荊戈   |  8020 | 1000 |    10 | 金   | 6    |
|  4 | 痕兮   |  8998 |  800 |   999 | 水   | 4    |
|  5 | 逐暮   |   100 | 1000 | 10000 | 火   | 5    |
|  6 | 風躍   |  9020 |   10 |    10 | 木   | 2    |
|  8 | 洛神   | 20020 |    1 |    10 | 金   | 3    |
| 9 | 隱鋒 | 8020 | 2000 | 10 | 土 | 1 | +----+--------+-------+------+-------+------+------+
8 rows in set (0.00 sec)
經過CREATE…SELECT來建立數據表而且同時寫入記錄

此時字段值必須爲sword中的attrrem

mysql> CREATE TABLE sword_attr ( -> attr_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, -> attr VARCHAR(4) NOT NULL -> ) SELECT attr FROM sword GROUP BY attr; Query OK, 5 rows affected (0.47 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> SELECT*FROM sword_attr;
+---------+------+
| attr_id | attr | +---------+------+
|       1 | 土   |
|       2 | 木   |
|       3 | 水   |
|       4 | 火   |
| 5 | 金 | +---------+------+
5 rows in set (0.00 sec)
若是兩表字段相同,這樣會報錯,需具體指定字段屬於哪張表
  • 錯誤:
mysql>   UPDATE sword INNER JOIN sword_attr
    -> ON attr = attr
    -> SET attr = attr_id;
ERROR 1052 (23000): Column 'attr' in field list is ambiguous
  • 正確
mysql>   UPDATE sword AS s INNER JOIN sword_attr AS a -> ON s.attr = a.attr -> SET s.attr = a.attr_id;
Query OK, 8 rows affected (0.00 sec)
Rows matched: 8  Changed: 8  Warnings: 0

mysql> SELECT*FROM sword; +----+--------+-------+------+-------+------+------+
| id | name | atk | hit | crit | attr | type | +----+--------+-------+------+-------+------+------+
|  1 | 黑風   | 10800 |  400 |   400 | 2    | 3    |
|  2 | 木藜   |  5400 |  200 |   200 | 2    | 1    |
|  3 | 荊戈   |  8020 | 1000 |    10 | 5    | 6    |
|  4 | 痕兮   |  8998 |  800 |   999 | 3    | 4    |
|  5 | 逐暮   |   100 | 1000 | 10000 | 4    | 5    |
|  6 | 風躍   |  9020 |   10 |    10 | 2    | 2    |
|  8 | 洛神   | 20020 |    1 |    10 | 5    | 3    |
| 9 | 隱鋒 | 8020 | 2000 | 10 | 1 | 1 | +----+--------+-------+------+-------+------+------+
8 rows in set (0.00 sec)
查看一下表信息:
mysql> DESC sword; +-------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra | +-------+----------------------+------+-----+---------+----------------+
| id    | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment | | name | varchar(32) | NO | | NULL | | | atk | smallint(5) unsigned | NO | | NULL | | | hit | smallint(5) unsigned | NO | | NULL | | | crit | smallint(5) unsigned | YES | | 10 | | | attr | varchar(4) | NO | | NULL | | | type | varchar(8) | NO | | NULL | | +-------+----------------------+------+-----+---------+----------------+ 7 rows in set (0.00 sec)

此時能夠改attr和type的類型爲數字,it

mysql>  ALTER TABLE sword
 -> CHANGE type type_id SMALLINT UNSIGNED NOT NULL,
 -> CHANGE attr attr_id SMALLINT UNSIGNED NOT NULL;
Query OK, 9 rows affected (0.05 sec)
Records: 9  Duplicates: 0  Warnings: 0

mysql> SELECT*FROM sword; +----+--------+-------+------+-------+---------+---------+
| id | name | atk | hit | crit | attr_id | type_id | +----+--------+-------+------+-------+---------+---------+
|  1 | 黑風   | 10800 |  400 |   400 |       2 |       3 |
|  2 | 木藜   |  5400 |  200 |   200 |       2 |       1 |
|  3 | 荊戈   |  8020 | 1000 |    10 |       5 |       6 |
|  4 | 痕兮   |  8998 |  800 |   999 |       3 |       4 |
|  5 | 逐暮   |   100 | 1000 | 10000 |       4 |       5 |
|  6 | 風躍   |  9020 |   10 |    10 |       2 |       2 |
|  8 | 洛神   | 20020 |    1 |    10 |       5 |       3 |
| 9 | 隱鋒 | 8020 | 2000 | 10 | 1 | 1 | +----+--------+-------+------+-------+---------+---------+
9 rows in set (0.01 sec)

mysql> DESC sword; +---------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra | +---------+----------------------+------+-----+---------+----------------+
| id      | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment | | name | varchar(32) | NO | | NULL | | | atk | smallint(5) unsigned | NO | | NULL | | | hit | smallint(5) unsigned | NO | | NULL | | | crit | smallint(5) unsigned | YES | | 10 | | | attr_id | smallint(5) unsigned | NO   |     | NULL    |                |
| type_id | smallint(5) unsigned | NO | | NULL | | +---------+----------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

這樣表中兩列重複漢字都用數字等價替換,減小表的體積。class

錶鏈接

添加兩條類型
mysql> INSERT sword_type(type_name) VALUES('獸界'),('佛界');
Query OK, 2 rows affected (0.42 sec)
Records: 2  Duplicates: 0  Warnings: 0
mysql> SELECT*FROM sword_type; +---------+-----------+
| type_id | type_name | +---------+-----------+
|       1 | 人界      |
|       2 | 仙界      |
|       3 | 神界      |
|       4 | 道界      |
|       5 | 鬼界      |
|       6 | 魔界      |
|       7 | 獸界      |
| 8 | 佛界 | +---------+-----------+
8 rows in set (0.00 sec)

添加兩條屬性sso

mysql> INSERT sword_attr(attr) VALUES('光'),('暗'); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> SELECT*FROM sword_attr; +---------+------+
| attr_id | attr | +---------+------+
|       1 | 土   |
|       2 | 木   |
|       3 | 水   |
|       4 | 火   |
|       5 | 金   |
|       6 | 光   |
| 7 | 暗 | +---------+------+
7 rows in set (0.01 sec)

插入一條數據:弒神(attr_id越界)

mysql> INSERT sword VALUES(NULL,'弒神',12000,100,100,10,6);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT*FROM sword; +----+--------+-------+------+-------+---------+---------+
| id | name | atk | hit | crit | attr_id | type_id | +----+--------+-------+------+-------+---------+---------+
|  1 | 黑風   | 10800 |  400 |   400 |       2 |       3 |
|  2 | 木藜   |  5400 |  200 |   200 |       2 |       1 |
|  3 | 荊戈   |  8020 | 1000 |    10 |       5 |       6 |
|  4 | 痕兮   |  8998 |  800 |   999 |       3 |       4 |
|  5 | 逐暮   |   100 | 1000 | 10000 |       4 |       5 |
|  6 | 風躍   |  9020 |   10 |    10 |       2 |       2 |
|  8 | 洛神   | 20020 |    1 |    10 |       5 |       3 |
|  9 | 隱鋒   |  8020 | 2000 |    10 |       1 |       1 |
| 10 | 弒神 | 12000 | 100 | 100 | 10| 6 | +----+--------+-------+------+-------+---------+---------+
10 rows in set (0.00 sec)
INNER JOIN

查詢全部劍的詳細信息(經過內鏈接實現:只呈現正確鏈接的記錄)
因爲弒神的attr_id越界,鏈接不正確,故沒法查出

mysql> SELECT id,name,atk,hit,type_name,attr FROM sword AS s -> INNER JOIN sword_type AS t ON s.type_id = t.type_id
 -> INNER JOIN sword_attr AS a ON s.attr_id = a.attr_id; +----+--------+-------+------+-----------+------+
| id | name | atk | hit | type_name | attr | +----+--------+-------+------+-----------+------+
|  1 | 黑風   | 10800 |  400 | 神界      | 木   |
|  2 | 木藜   |  5400 |  200 | 人界      | 木   |
|  3 | 荊戈   |  8020 | 1000 | 魔界      | 金   |
|  4 | 痕兮   |  8998 |  800 | 道界      | 水   |
|  5 | 逐暮   |   100 | 1000 | 鬼界      | 火   |
|  6 | 風躍   |  9020 |   10 | 仙界      | 木   |
|  8 | 洛神   | 20020 |    1 | 神界      | 金   |
| 9 | 隱鋒 | 8020 | 2000 | 人界 | 土 | +----+--------+-------+------+-----------+------+
8 rows in set (0.00 sec)
LEFT JOIN

查詢全部劍的詳細信息(左外鏈接:左表所有,右表無匹配則置空)

mysql> SELECT id,name,atk,hit,type_name,attr FROM sword AS s -> LEFT JOIN sword_type AS t ON s.type_id = t.type_id
 -> LEFT JOIN sword_attr AS a ON s.attr_id = a.attr_id; +----+--------+-------+------+-----------+------+
| id | name | atk | hit | type_name | attr | +----+--------+-------+------+-----------+------+
|  1 | 黑風   | 10800 |  400 | 神界      | 木   |
|  2 | 木藜   |  5400 |  200 | 人界      | 木   |
|  3 | 荊戈   |  8020 | 1000 | 魔界      | 金   |
|  4 | 痕兮   |  8998 |  800 | 道界      | 水   |
|  5 | 逐暮   |   100 | 1000 | 鬼界      | 火   |
|  6 | 風躍   |  9020 |   10 | 仙界      | 木   |
|  8 | 洛神   | 20020 |    1 | 神界      | 金   |
|  9 | 隱鋒   |  8020 | 2000 | 人界      | 土   |
| 10 | 弒神 | 12000 | 100 | 魔界 | NULL | +----+--------+-------+------+-----------+------+
9 rows in set (0.00 sec)
RIGHT JOIN

查詢全部劍的詳細信息(左外鏈接:右表所有,左表無匹配則置空)

mysql> SELECT id,name,atk,hit,type_name,attr FROM sword AS s -> RIGHT JOIN sword_type AS t ON s.type_id = t.type_id
 -> RIGHT JOIN sword_attr AS a ON s.attr_id = a.attr_id; +------+--------+-------+------+-----------+------+
| id | name | atk | hit | type_name | attr | +------+--------+-------+------+-----------+------+
|    9 | 隱鋒   |  8020 | 2000 | 人界      | 土   |
|    1 | 黑風   | 10800 |  400 | 神界      | 木   |
|    2 | 木藜   |  5400 |  200 | 人界      | 木   |
|    6 | 風躍   |  9020 |   10 | 仙界      | 木   |
|    4 | 痕兮   |  8998 |  800 | 道界      | 水   |
|    5 | 逐暮   |   100 | 1000 | 鬼界      | 火   |
|    3 | 荊戈   |  8020 | 1000 | 魔界      | 金   |
|    8 | 洛神   | 20020 |    1 | 神界      | 金   |
| NULL | NULL   |  NULL | NULL | NULL      | 光   |
| NULL | NULL | NULL | NULL | NULL | 暗 | +------+--------+-------+------+-----------+------+
10 rows in set (0.00 sec)
相關文章
相關標籤/搜索