1. 程式人生 > 實用技巧 >MySQL資料庫之select查詢語句

MySQL資料庫之select查詢語句

select查詢語句

  • 語法
    • select [選項] 列名 [from 表名] [where 條件] [group by 分組] [order by 排序][having 條件] [limit 限制]

select欄位表示式

  • 可以直接輸出內容
MariaDB [sel]> select 'Sunny is a boy!';
+-----------------+
| Sunny is a boy! |
+-----------------+
| Sunny is a boy! |
+-----------------+
# `1 row in set (0.000 sec)`
  • 輸出表達式
MariaDB [sel]> select 10*27;
+-------+
| 10*27 |
+-------+
|   270 |
+-------+
# `1 row in set (0.000 sec)`
MariaDB [sel]> select name,chinese,math,chinese+math from grades;
+-------+---------+------+--------------+
| name  | chinese | math | chinese+math |
+-------+---------+------+--------------+
| Sunny |      93 |   96 |          189 |
| Jerry |      97 |   91 |          188 |
| Marry |      95 |   94 |          189 |
| Tommy |      98 |   94 |          192 |
+-------+---------+------+--------------+
# `4 rows in set (0.000 sec)`
  • 輸出函式表示式
MariaDB [sel]> select rand();
+-------------------+
| rand()            |
+-------------------+
| 0.294372641755615 |
+-------------------+
# `1 row in set (0.007 sec)`
  • 通過as給欄位取別名
    • as可以省略
MariaDB [sel]> select 'Sunny' as 'name';
+-------+
| name  |
+-------+
| Sunny |
+-------+
# `1 row in set (0.000 sec)`

MariaDB [sel]> select name,chinese,math,chinese+math as '總分' from grades;
+-------+---------+------+------+
| name  | chinese | math | 總分 |
+-------+---------+------+------+
| Sunny |      93 |   96 |  189 |
| Jerry |      97 |   91 |  188 |
| Marry |      95 |   94 |  189 |
| Tommy |      98 |   94 |  192 |
+-------+---------+------+------+
# `4 rows in set (0.007 sec)`

MariaDB [sel]> select name,chinese,math,chinese+math '總分' from grades;
+-------+---------+------+------+
| name  | chinese | math | 總分 |
+-------+---------+------+------+
| Sunny |      93 |   96 |  189 |
| Jerry |      97 |   91 |  188 |
| Marry |      95 |   94 |  189 |
| Tommy |      98 |   94 |  192 |
+-------+---------+------+------+
# `4 rows in set (0.001 sec)`

from子句

  • from [表名]
    • from後面跟的是資料來源
    • 資料來源可以有多個,返回笛卡爾積
-- 建立資料表
MariaDB [sel]> create table stu1(
    -> name varchar(20)
    -> )charset=gbk;
# `Query OK, 0 rows affected (0.026 sec)`

MariaDB [sel]> insert into stu1 values ('Sunny'),('Jerry');
# `Query OK, 2 rows affected (0.012 sec)`
# `Records: 2  Duplicates: 0  Warnings: 0`

MariaDB [sel]> create table stu2(
    -> age int
    -> )charset=gbk;
# `Query OK, 0 rows affected (0.023 sec)`

MariaDB [sel]> insert into stu2 values (20),(24);
# `Query OK, 2 rows affected (0.012 sec)`
# `Records: 2  Duplicates: 0  Warnings: 0`
-- from子句查詢
MariaDB [sel]> select * from stu1;
+-------+
| name  |
+-------+
| Sunny |
| Jerry |
+-------+
# `2 rows in set (0.000 sec)`
-- from返回笛卡爾積
MariaDB [sel]> select * from stu1,stu2;
+-------+------+
| name  | age  |
+-------+------+
| Sunny |   20 |
| Jerry |   20 |
| Sunny |   24 |
| Jerry |   24 |
+-------+------+
# `4 rows in set (0.000 sec)`

dual表

  • 概念
    • dual表是一個偽表
    • 在有些特定情況下,沒有具體的表的參與
    • 為了保證select語句的完整又必須要一個表名,這時候就使用偽表
MariaDB [sel]> select 10*27 as '結果' from dual;
+------+
| 結果 |
+------+
|  270 |
+------+
# `1 row in set (0.007 sec)`

where子句

  • 概念

    • where後面跟的是條件,在資料來源中進行篩選
    • 返回條件為真記錄
  • MySQL支援的運算子

    • 比較運算子
      • > 大於
      • < 小於
      • >= 大於等於
      • <= 小於等於
      • = 等於
      • != 不等於
    • 邏輯運算子
      • and
      • or
      • not
    • 其他
      • in | not in 欄位的值在列舉範圍內
      • between...and | not between...and 欄位的值在數字範圍內
      • is null | is not null 欄位的值不為空
-- 比較運算判斷
MariaDB [sel]> select * from grades where math=94;
+-------+---------+------+
| name  | chinese | math |
+-------+---------+------+
| Marry |      95 |   94 |
| Tommy |      98 |   94 |
+-------+---------+------+
# `2 rows in set (0.007 sec)`
-- 輸出所有資料
MariaDB [sel]> select * from grades where 1;
+-------+---------+------+
| name  | chinese | math |
+-------+---------+------+
| Sunny |      93 |   96 |
| Jerry |      97 |   91 |
| Marry |      95 |   94 |
| Tommy |      98 |   94 |
+-------+---------+------+
# `4 rows in set (0.000 sec)`

-- 不輸出資料
MariaDB [sel]> select * from grades where 0;
# `Empty set (0.000 sec)`
-- 邏輯運算判斷
MariaDB [sel]> select * from grades where math=96 or math=91;
+-------+---------+------+
| name  | chinese | math |
+-------+---------+------+
| Sunny |      93 |   96 |
| Jerry |      97 |   91 |
+-------+---------+------+
# `2 rows in set (0.001 sec)`

MariaDB [sel]> select * from grades where math in (91,96);
+-------+---------+------+
| name  | chinese | math |
+-------+---------+------+
| Sunny |      93 |   96 |
| Jerry |      97 |   91 |
+-------+---------+------+
# `2 rows in set (0.000 sec)`

MariaDB [sel]> select * from grades where math not in (91,96);
+-------+---------+------+
| name  | chinese | math |
+-------+---------+------+
| Marry |      95 |   94 |
| Tommy |      98 |   94 |
+-------+---------+------+
# `2 rows in set (0.000 sec)`
  • 查詢年齡在20~25之間
-- 方法一:
mysql> select * from stu where stuage>=20 and stuage<=25;

-- 方法二:
mysql> select * from stu where not(stuage<20 or stuage>25);

-- 方法三:between...and...
mysql> select * from stu where stuage between 20 and 25;

-- 年齡不在20~25之間
mysql> select * from stu where stuage not between 20 and 25;
  • 查詢缺考的學生
mysql> select * from stu where ch is null or math is null;
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25301 | 張秋麗    | 男     |    18 |       1 | 北京        |   80 | NULL |
| s25304 | 歐陽俊雄  | 男     |    28 |       4 | 天津        | NULL |   74 |
+--------+----------+--------+--------+---------+------------+------+------+
  • 查詢沒有缺考的學生
mysql> select * from stu where ch is not null and math is not null;
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25302 | 李文才    | 男     |     31 |       3 | 上海       |   77 |   76 |
| s25303 | 李斯文    | 女     |     22 |       2 | 北京       |   55 |   82 |
| s25305 | 諸葛麗麗  | 女     |     23 |       7 | 河南       |   72 |   56 |
| s25318 | 爭青小子  | 男     |     26 |       6 | 天津       |   86 |   92 |
| s25319 | 梅超風    | 女     |     23 |       5 | 河北       |   74 |   67 |
| s25320 | Tom      | 男     |     24 |       8 | 北京       |   65 |   67 |
| s25321 | Tabm     | 女     |     23 |       9 | 河北       |   88 |   77 |
+--------+----------+--------+--------+---------+------------+------+------+
# `7 rows in set (0.00 sec)`
  • 查詢需要補考的學生
mysql> select * from stu where ch<60 or math<60 or ch is null or math is null;
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25301 | 張秋麗    | 男    |     18 |       1 | 北京        |   80 | NULL |
| s25303 | 李斯文    | 女    |     22 |       2 | 北京        |   55 |   82 |
| s25304 | 歐陽俊雄  | 男    |     28 |       4 | 天津        | NULL |   74 |
| s25305 | 諸葛麗麗  | 女    |     23 |       7 | 河南        |   72 |   56 |
+--------+----------+--------+--------+---------+------------+------+------+
4 rows in set (0.00 sec)
  • 查詢學號是s25301,s25302,s25303的學生
mysql> select * from stu where stuno in ('s25301','s25302','s25303');
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25301 | 張秋麗   | 男     |     18 |       1 | 北京       |   80 | NULL |
| s25302 | 李文才   | 男     |     31 |       3 | 上海       |   77 |   76 |
| s25303 | 李斯文   | 女     |     22 |       2 | 北京       |   55 |   82 |
+--------+---------+--------+--------+---------+------------+------+------+
# `3 rows in set (0.00 sec)`
  • 查詢年齡是18~20的學生
mysql> select * from stu where stuage between 18 and 20;
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25301 | 張秋麗  | 男     |     18 |       1 | 北京        |   80 | NULL |
+--------+---------+--------+--------+---------+------------+------+------+
1 row in set (0.00 sec)

group by [分組查詢]

  • 概念
    • 將查詢的結果分組,分組查詢目的在於統計資料
    • 如果是分組查詢,查詢欄位是分組欄位和聚合函式
    • 查詢欄位是普通欄位,只取第一個值
    • group_concat()將同一組的資料連線起來
-- 查詢男生和女生的各自語文平均分
mysql> select stusex,avg(ch) '平均分' from stu group by stusex;
+--------+---------+
| stusex | 平均分  |
+--------+---------+
| 女     | 72.2500 |
| 男     | 77.0000 |
+--------+---------+
# `2 rows in set (0.00 sec)`

-- 查詢男生和女生各自多少人
mysql> select stusex,count(*) 人數 from stu group by stusex;
+--------+------+
| stusex | 人數 |
+--------+------+
| 女     |    4 |
| 男     |    5 |
+--------+------+
# `2 rows in set (0.00 sec)`

-- 查詢每個地區多少人
mysql> select stuaddress,count(*) from stu group by stuaddress;
+------------+----------+
| stuaddress | count(*) |
+------------+----------+
| 上海       |        1 |
| 北京       |        3 |
| 天津       |        2 |
| 河北       |        2 |
| 河南       |        1 |
+------------+----------+
# `5 rows in set (0.00 sec)`

-- 每個地區的數學平均分
mysql> select stuaddress,avg(math) from stu group by stuaddress;
+------------+-----------+
| stuaddress | avg(math) |
+------------+-----------+
| 上海       |   76.0000 |
| 北京       |   74.5000 |
| 天津       |   83.0000 |
| 河北       |   72.0000 |
| 河南       |   56.0000 |
+------------+-----------+
# `5 rows in set (0.00 sec)`
  • group_concat() 函式
    • 將同一組的值連線起來顯示
mysql> select group_concat(stuname),stusex,avg(math) from stu group by stusex;
+-------------------------------------+--------+-----------+
| group_concat(stuname)               | stusex | avg(math) |
+-------------------------------------+--------+-----------+
| 李斯文,諸葛麗麗,梅超風,Tabm           | 女     |   70.5000 |
| 張秋麗,李文才,歐陽俊雄,爭青小子,Tom    | 男    |   77.2500 |
+-------------------------------------+--------+-----------+
# `2 rows in set (0.00 sec)`
  • 多列分組
mysql> select stuaddress,stusex,avg(math) from stu group by stuaddress,stusex;
+------------+--------+-----------+
| stuaddress | stusex | avg(math) |
+------------+--------+-----------+
| 上海       | 男     |   76.0000 |
| 北京       | 女     |   82.0000 |
| 北京       | 男     |   67.0000 |
| 天津       | 男     |   83.0000 |
| 河北       | 女     |   72.0000 |
| 河南       | 女     |   56.0000 |
+------------+--------+-----------+
# `6 rows in set (0.00 sec)`

order by [排序]

  • asc 升序 [預設]
  • desc 降序
MariaDB [sel]> select * from grades order by math desc;
+-------+---------+------+
| name  | chinese | math |
+-------+---------+------+
| Sunny |      93 |   96 |
| Marry |      95 |   94 |
| Tommy |      98 |   94 |
| Jerry |      97 |   91 |
+-------+---------+------+
# `4 rows in set (0.001 sec)`

-- 按總分降序排列
MariaDB [sel]> select *,chinese+math  from grades order by math+chinese desc;
+-------+---------+------+--------------+
| name  | chinese | math | chinese+math |
+-------+---------+------+--------------+
| Tommy |      98 |   94 |          192 |
| Sunny |      93 |   96 |          189 |
| Marry |      95 |   94 |          189 |
| Jerry |      97 |   91 |          188 |
+-------+---------+------+--------------+
# `4 rows in set (0.001 sec)`

MariaDB [sel]> select *,chinese+math '總分'  from grades order by math+chinese desc;
+-------+---------+------+------+
| name  | chinese | math | 總分 |
+-------+---------+------+------+
| Tommy |      98 |   94 |  192 |
| Sunny |      93 |   96 |  189 |
| Marry |      95 |   94 |  189 |
| Jerry |      97 |   91 |  188 |
+-------+---------+------+------+
# `4 rows in set (0.000 sec)`
  • 多列排序
    • 前列為主,後列為輔
MariaDB [sel]> select * from grades order by math desc,chinese asc;
+-------+---------+------+
| name  | chinese | math |
+-------+---------+------+
| Sunny |      93 |   96 |
| Marry |      95 |   94 |
| Tommy |      98 |   94 |
| Jerry |      97 |   91 |
+-------+---------+------+
# `4 rows in set (0.000 sec)`

having條件

  • 概念

    • 是在結果集上進行條件篩選
  • havingwhere的區別

    • where是對原始資料進行篩選
    • having是對記錄集進行篩選
-- having與where相同
MariaDB [sel]> select * from grades where math=94;
+-------+---------+------+
| name  | chinese | math |
+-------+---------+------+
| Marry |      95 |   94 |
| Tommy |      98 |   94 |
+-------+---------+------+
# `2 rows in set (0.000 sec)`

MariaDB [sel]> select * from grades having math=94;
+-------+---------+------+
| name  | chinese | math |
+-------+---------+------+
| Marry |      95 |   94 |
| Tommy |      98 |   94 |
+-------+---------+------+
# 2 rows in set (0.000 sec)
-- having與where不同
MariaDB [sel]> select name from grades where math=94;
+-------+
| name  |
+-------+
| Marry |
| Tommy |
+-------+
# `2 rows in set (0.000 sec)`

MariaDB [sel]> select name from grades having math=94;
# `ERROR 1054 (42S22): Unknown column 'math' in 'having clause'`

limit

  • 語法
    • limit [起始位置],顯示長度
-- 從第0個位置開始取,取3條記錄
mysql> select * from stu limit 0,3;

-- 從第2個位置開始取,取3條記錄
mysql> select * from stu limit 2,3;
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25303 | 李斯文    | 女     |     22 |       2 | 北京       |   55 |   82 |
| s25304 | 歐陽俊雄  | 男     |     28 |       4 | 天津       | NULL |   74 |
| s25305 | 諸葛麗麗  | 女     |     23 |       7 | 河南       |   72 |   56 |
+--------+----------+--------+--------+---------+------------+------+------+
# `3 rows in set (0.00 sec)`
  • 起始位置可以省略,預設是從0開始
mysql> select * from stu limit 3;
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25301 | 張秋麗  | 男     |     18 |       1 | 北京        |   80 | NULL |
| s25302 | 李文才  | 男     |     31 |       3 | 上海        |   77 |   76 |
| s25303 | 李斯文  | 女     |     22 |       2 | 北京        |   55 |   82 |
+--------+---------+--------+--------+---------+------------+------+------+
# `3 rows in set (0.00 sec)`
  • 找出班級總分前三名
mysql> select *,ch+math total from stu order by (ch+math) desc limit 0,3;
+--------+----------+--------+--------+---------+------------+------+------+-------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math | total |
+--------+----------+--------+--------+---------+------------+------+------+-------+
| s25318 | 爭青小子  | 男     |     26 |       6 | 天津       |   86 |   92 |   178 |
| s25321 | Tabm     | 女     |     23 |       9 | 河北       |   88 |   77 |   165 |
| s25302 | 李文才   | 男     |     31 |       3 | 上海        |   77 |   76 |   153 |
+--------+----------+--------+--------+---------+------------+------+------+-------+
# `3 rows in set (0.00 sec)`
  • limit在update和delete語句中也是可以使用的
-- 前3名語文成績加1分
mysql> update stu set ch=ch+1 order by ch+math desc limit 3;
# `Query OK, 3 rows affected (0.00 sec)`
# `Rows matched: 3  Changed: 3  Warnings: 0`
-- 前3名刪除
mysql> delete from stu order by ch+math desc limit 3;
# `Query OK, 3 rows affected (0.00 sec)`

查詢語句中的選項distinct

  • 查詢語句中的選項有兩個
    • all 顯示所有資料 [預設]
    • distinct 去除結果集中重複的資料
-- 顯示列所有資料
MariaDB [sel]> select all math from grades;
+------+
| math |
+------+
|   96 |
|   91 |
|   94 |
|   94 |
+------+
# `4 rows in set (0.001 sec)`
-- 單列去除重複的項
MariaDB [sel]> select distinct math from grades;
+------+
| math |
+------+
|   96 |
|   91 |
|   94 |
+------+
# `3 rows in set (0.001 sec)`