1. 程式人生 > >mysql 命令列操作(四)高階sql語句

mysql 命令列操作(四)高階sql語句

1.union,連線兩個以上的select語句的結果組合到一個結果集中,多個select語句中相同的資料會被刪除,多個union的select語句必須列數相同,比如第一個select選擇兩個列,那麼後續所有union的select語句都必須是兩列,不要求列的屬性一致,可以用union all保留所有重複的資料。用於測試的兩個表資料如下:

mysql> select * from app;
+----+------------+-------------------------+---------+
| id | app_name   | url                     | country |
+----+------------+-------------------------+---------+
|  1 | QQ APP     | http://im.qq.com/       | CN      |
|  2 | 微博 APP   | http://weibo.com/       | CN      |
|  3 | 淘寶 APP   | https://www.taobao.com/ | CN      |
+----+------------+-------------------------+---------+
3 rows in set (0.00 sec)

mysql> select * from website
    -> ;
+----+---------------+---------------------------+-------+---------+
| id | name          | url                       | alexa | country |
+----+---------------+---------------------------+-------+---------+
|  1 | Google        | https://www.google.com/   |     1 | USA     |
|  2 | 淘寶          | https:/www.taobao.com/    |    13 | CN      |
|  3 | 菜鳥教程      | http://www.runoob.com     |  4689 | CN      |
|  4 | 微博          | http://weibo.com/         |    20 | CN      |
|  5 | Facebook      | https://www.facebook.com/ |     3 | USA     |
|  6 | stackoverflow | http://stackoverflow.com/ |     0 | IND     |
+----+---------------+---------------------------+-------+---------+
6 rows in set (0.00 sec)

將兩個表中列為country的選出來並按照country排序

mysql> select country from website
    -> union
    -> select country from website
    -> order by country;
+---------+
| country |
+---------+
| CN      |
| IND     |
| USA     |
+---------+
3 rows in set (0.00 sec)

使用union all不刪除重複的資料

mysql> select country from website
    -> union all
    -> select country from app
    -> order by country;
+---------+
| country |
+---------+
| CN      |
| CN      |
| CN      |
| CN      |
| CN      |
| CN      |
| IND     |
| USA     |
| USA     |
+---------+
9 rows in set (0.00 sec)

使用union合併使用where的select語句

mysql> select country, name from website where country = 'CN'
    -> union
    -> select country, app_name from app where country = 'CN';
+---------+--------------+
| country | name         |
+---------+--------------+
| CN      | 淘寶         |
| CN      | 菜鳥教程     |
| CN      | 微博         |
| CN      | QQ APP       |
| CN      | 微博 APP     |
| CN      | 淘寶 APP     |
+---------+--------------+
6 rows in set (0.00 sec)

2.排序語句order by:使用select語句可以查詢,可以使用order語句將查詢的結果排序後返回,可以選擇多個欄位進行排序,可以使用ASC或者DESC進行升序或者降序,預設是升序,根據alexa欄位進行排序的一個例子:

mysql> select * from website order by alexa asc;
+----+---------------+---------------------------+-------+---------+
| id | name          | url                       | alexa | country |
+----+---------------+---------------------------+-------+---------+
|  6 | stackoverflow | http://stackoverflow.com/ |     0 | IND     |
|  1 | Google        | https://www.google.com/   |     1 | USA     |
|  5 | Facebook      | https://www.facebook.com/ |     3 | USA     |
|  2 | 淘寶          | https:/www.taobao.com/    |    13 | CN      |
|  4 | 微博          | http://weibo.com/         |    20 | CN      |
|  3 | 菜鳥教程      | http://www.runoob.com     |  4689 | CN      |
+----+---------------+---------------------------+-------+---------+
6 rows in set (0.00 sec)

3.分組語句 group by:根據一個列或者多個對資料集進行分組,在分組的列上可以使用COUNT,SUM,AVG等函式,測試資料表如下:

mysql> select * from employee_tbl;
+----+--------+---------------------+--------+
| id | name   | date                | singin |
+----+--------+---------------------+--------+
|  1 | 小明   | 2016-04-22 15:25:33 |      1 |
|  2 | 小王   | 2016-04-20 15:25:47 |      3 |
|  3 | 小麗   | 2016-04-19 15:26:02 |      2 |
|  4 | 小王   | 2016-04-07 15:26:14 |      4 |
|  5 | 小明   | 2016-04-11 15:26:40 |      4 |
|  6 | 小明   | 2016-04-04 15:26:54 |      2 |
+----+--------+---------------------+--------+
6 rows in set (0.00 sec)

根據name進行分組並統計計數:

mysql> select name, count(*) from employee_tbl group by name;
+--------+----------+
| name   | count(*) |
+--------+----------+
| 小麗   |        1 |
| 小明   |        3 |
| 小王   |        2 |
+--------+----------+
3 rows in set (0.00 sec)

根據name進行分組並計算singin之和:

mysql> select name, sum(singin) from employee_tbl group by name;
+--------+-------------+
| name   | sum(singin) |
+--------+-------------+
| 小麗   |           2 |
| 小明   |           7 |
| 小王   |           7 |
+--------+-------------+
3 rows in set (0.00 sec)

使用with rollup語句對統計後的資料計算總數和,並使用as語句改變輸出的屬性值:

mysql> select name, sum(singin) as sum from employee_tbl group by name with rollup;
+--------+------+
| name   | sum  |
+--------+------+
| 小麗   |    2 |
| 小明   |    7 |
| 小王   |    7 |
| NULL   |   16 |
+--------+------+
4 rows in set (0.00 sec)

這裡總數是NULL,可以指定名字,方法是使用coalesce函式,函式原型coalesce(a, b, c)若a是NULL,選擇b,若b是NULL,選擇c,如下:

mysql> select coalesce(name, '總數'), sum(singin) as sum_count from employee_tbl group by name with rollup;
+--------------------------+-----------+
| coalesce(name, '總數')   | sum_count |
+--------------------------+-----------+
| 小麗                     |         2 |
| 小明                     |         7 |
| 小王                     |         7 |
| 總數                     |        16 |
+--------------------------+-----------+
4 rows in set (0.01 sec)

3.join語句:以上所有內容都是對於單個表的,union也是先查詢單張表然後查詢結果,join提供多表聯合查詢操作,可以在select、delete、update語句中使用。

join有3種:

inner join:內連線,獲取兩個表中欄位匹配的記錄

left join:左連線,獲取左表所有記錄,即使右表沒有對應匹配記錄

right join:右連線,獲取右表所有記錄,即使左表沒有對應匹配記錄

例如對如下兩張表,多表聯合查詢的含義就是,用runoob中的author欄位中的值,去tcount表中查runoob_count欄位的值

mysql> select * from runoob_tbl;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
|         1 | 學習 PHP      | 菜鳥教程      | 2017-04-12      |
|         2 | 學習 MySQL    | 菜鳥教程      | 2017-04-12      |
|         3 | 學習 Java     | RUNOOB.COM    | 2015-05-01      |
|         4 | 學習 Python   | RUNOOB.COM    | 2016-03-06      |
|         5 | 學習 C        | FK            | 2017-04-05      |
+-----------+---------------+---------------+-----------------+
5 rows in set (0.00 sec)

mysql> select * from tcount_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鳥教程      |           10 |
| RUNOOB.COM    |           20 |
| Google        |           22 |
+---------------+--------------+
3 rows in set (0.00 sec)

使用inner join語句效果如下:

mysql> select a.runoob_id, a.runoob_author, b.runoob_count from runoob_tbl a inner join tcount_tbl b
    -> on a.runoob_author = b.runoob_author;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
|         1 | 菜鳥教程      |           10 |
|         2 | 菜鳥教程      |           10 |
|         3 | RUNOOB.COM    |           20 |
|         4 | RUNOOB.COM    |           20 |
+-----------+---------------+--------------+

等價於使用如下where語句:

mysql> select a.runoob_id, a.runoob_author, b.runoob_count from runoob_tbl a, tcount_tbl b where a.runoob_author = b.runoob_author;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
|         1 | 菜鳥教程      |           10 |
|         2 | 菜鳥教程      |           10 |
|         3 | RUNOOB.COM    |           20 |
|         4 | RUNOOB.COM    |           20 |
+-----------+---------------+--------------+
4 rows in set (0.15 sec)

使用left join,會顯示左邊全部內容,即使在右表中沒有資料,沒有資料的屬性會顯示為NULL,如下

mysql> select a.runoob_id, a.runoob_author, b.runoob_count from runoob_tbl a left join tcount_tbl b
    -> on a.runoob_author = b.runoob_author;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
|         1 | 菜鳥教程      |           10 |
|         2 | 菜鳥教程      |           10 |
|         3 | RUNOOB.COM    |           20 |
|         4 | RUNOOB.COM    |           20 |
|         5 | FK            |         NULL |
+-----------+---------------+--------------+

使用right join,會顯示右表全部內容,在左表中沒有內容的屬性會顯示為NULL

mysql> select a.runoob_id, a.runoob_author, b.runoob_count from runoob_tbl a right join tcount_tbl b
    -> on a.runoob_author = b.runoob_author;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
|         1 | 菜鳥教程      |           10 |
|         2 | 菜鳥教程      |           10 |
|         3 | RUNOOB.COM    |           20 |
|         4 | RUNOOB.COM    |           20 |
|      NULL | NULL          |           22 |
+-----------+---------------+--------------+

4.NULL值的處理:mysql中的NULL值和程式語言中的NULL值比比較特殊,NULL和任何值比較都返回false,即使是NULL = NULL,因此不能用=和!=對NULL進行比較,mysql提供的專門的運算子解決這個問題,有3種:

IS NULL:當列的值是NULL,返回true

IS NOT NULL:當列的值不為NULL,返回true

<==>:當比較的兩個值都是NULL的時候,返回true

例如,對如下資料表進行操作,使用”=“判斷是否是NULL不生效

mysql> select * from runoob_test_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| RUNOOB        |           20 |
| 菜鳥教程      |         NULL |
| Google        |         NULL |
| FK            |           20 |
+---------------+--------------+
4 rows in set (0.00 sec)

mysql> select * from runoob_test_tbl where runoob_count = NULL;
Empty set (0.01 sec)

mysql> select * from runoob_test_tbl where runoob_count is null;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鳥教程      |         NULL |
| Google        |         NULL |
+---------------+--------------+