1. 程式人生 > 實用技巧 >資料庫的查詢

資料庫的查詢

1.構造資料

為了操作方便, 先構造以下資料

1.1 學生表

create table `student` (
`id` int unsigned primary key auto_increment,
`name` char(32) not null unique,
`sex` enum('', '') not null,
`city` char(32) not null,
`description` text,
`birthday` date not null default '1995-1-1',
`money` float(7, 2) default 0,
`only_child` boolean
) charset
=utf8; insert into `student` (`name`, `sex`, `city`, `description`, `birthday`, `money`, `only_child`) values ('郭德綱', '', '北京', '班長', '1997/10/1', rand() * 100, True), ('陳喬恩', '', '上海', NULL, '1995/3/2', rand() * 100, True), ('趙麗穎', '', '北京', '班花, 不驕傲', '1995/4/4', rand() * 100, False), ('王寶強', '', '重慶', '超愛吃火鍋
', '1998/10/5', rand() * 100, False), ('趙雅芝', '', '重慶', '全宇宙三好學生', '1996/7/9', rand() * 100, True), ('張學友', '', '上海', '奧林匹克總冠軍!', '1993/5/2', rand() * 100, False), ('陳意涵', '', '上海', NULL, '1994/8/30', rand() * 100, True), ('趙本山', '', '南京', '副班長', '1995/6/1', rand() * 100, True), ('張柏芝', '', '上海', NULL, '1997/2/28', rand() * 100
, False), ('吳亦凡', '', '南京', '大碗寬面要不要?', '1995/6/1', rand() * 100, True), ('鹿晗', '', '北京', NULL, '1993/5/28', rand() * 100, True), ('關曉彤', '', '北京', NULL, '1995/7/12', rand() * 100, True), ('周杰倫', '', '臺北', '小夥人才啊', '1998/3/28', rand() * 100, False), ('馬雲', '', '南京', '一個字:賊有錢', '1990/4/1', rand() * 100, False), ('馬化騰', '', '上海', '馬雲死對頭', '1990/11/28', rand() * 100, False);

1.2成績表

create table score (
  `id` int unsigned primary key auto_increment,
  `math` float not null default 0,
  `english` float not null default 0
) charset=utf8;
insert into score (`math`, `english`)
values
(49, 71), (62, 66.7), (44, 86), (77.5, 74), (41, 75),
(82, 59.5), (64.5, 85), (62, 98), (44, 36), (67, 56),
(81, 90), (78, 70), (83, 66), (40, 90), (90, 90);

2.常用的查詢語句

2.1SELECT : 欄位表示式

  • SELECT 既可以做查詢, 也可以做輸出
  • 示例
select rand(); -- 隨機數
select unix_timestamp(); -- 顯示Unix時間戳
select id, name from student;

2.2FROM 子句

  • 語法: select 欄位 from 表名;
  • FROM 後面是資料來源, 資料來源可以寫多個, 資料來源一般是表名, 也可以是其他查詢的結果;
  • 示例
SELECT student.name, score.math FROM student, score;

2.3WHERE 子句: 按指定條件過濾

  • 語法: select 欄位 from 表名 where 條件;
  • WHERE 是做條件查詢, 只返回結果為 True 的資料
  • 示例
select name from student where city = '上海';
  • 空值判斷: is null | is not null
select `name` from `student` where `description` is null;
select `name` from `student` where `description` is not null;
  • 範圍判斷:
  • between ... and ...
  • not between ... and ...
select id, math from score where math between 60 and 70;
select id, math from score where math not between 60 and 70;
select * from score where math>=80 and english<=60; -- 直接做比較判斷

2.4HAVING

  • HAVING 和WHERE 功能類似,都可以用來實現條件查詢。很多情況下可以用where 或者having ,甚至可以混合使用。
  • 示例:
select `name`, `birthday` from `student` where `birthday` > '1995-1-1';
select `name`, `birthday` from `student` having `birthday` > '1995-1-1';
select * from student where id>=3 and city='北京';
select * from student having id>=3 and city='北京';
select * from student where id>=3 having city='北京'; -- 混用

  但是他們也有區別。

  • 只能使用where不能使用having的情況。
select `name`, `birthday` from `student` where id > 2;
-- 報錯,having的條件查詢,只能包含在前面的搜尋結果裡
select `name`, `birthday` from `student` having id > 2;
  • 只能使用having不能使用where的情況。
select name as n,birthday as b,id as i from student having i > 2;
-- 報錯,where只識別存在的欄位
select name as n,birthday as b,id as i from student where i > 2;
-- 取出每個城市中滿足最小出生年份大於1995的
select city, group_concat(birthday) from student group by city having min(birthday) > '1995-1-1';

2.5GROUP BY : 分組查詢

  • 按照某一欄位進行分組, 會把該欄位中值相同的歸為一組, 將查詢的結果分類顯示, 方便統計。
  • 如果有 WHERE 要放在 WHERE 的後面
  • 語法: select 欄位 from 表名 group by 分組欄位;
  • 示例
select sex, count(id) from student group by sex;
-- 在group將需要的結果通過 “聚合函式” 拼接
select sex, group_concat(name) from student group by sex;

2.6ORDER BY : 按欄位排序

  • ORDER BY 主要作用是排序
  • ORDER BY 寫在 GROUP BY 後面 ,如果有 HAVING 也要寫在 HAVING 的後面
  • 語法: select 欄位 from 表名 order by 排序欄位 asc|desc;
  • 分為升序 asc 降序 desc, 預設 asc (可以不寫)
  • 示例
select * from student order by age;
select * from student order by age desc;
select city,avg(money),group_concat(name),sum(money) from student group by city having sum(money)>70 order by sum(money);

2.7LIMIT : 限制取出數量

語法:

select 欄位 from 表名 limit m; -- 從第 1 行到第 m 行
select 欄位 from 表名 limit m, n; -- 從第 m 行開始,往下取 n 行
select 欄位 from 表名 limit m offset n; -- 跳過前 n 行, 取後面的 m 行

2.8DISTINCT : 去重

示例:

select distinct city from student;

2.9dual表

dual 是一個虛擬表, 僅僅為了保證 select ... from ... 語句的完整性

3.函式

3.1聚合函式

3.2數值計算類函式

3.3日期計算類函式

3.4字串相關函式

3.5其他函式

4.多表查詢

4.1UNION 聯合查詢

UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。

union要求:

  • 1. 兩邊 select 語句的欄位數必須一樣
  • 2. 兩邊可以具有不同資料型別的欄位
  • 3. 欄位名預設按照左邊的表來設定
  • 4. 用法:
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;

4.2INNER JOIN : 內連線 (交集)

  • INNER JOIN 關鍵字在表中存在至少一個匹配時返回行。
  • 語法
SELECT 欄位
FROM 表1 INNER JOIN 表2
ON 表1.欄位=表2.欄位;
-- 或:
SELECT column_name(s)
FROM table1 JOIN table2
ON table1.column_name=table2.column_name;

4.3LEFT JOIN : 左連線

LEFT JOIN 關鍵字從左表(table1)返回所有的行,即使右表(table2)中沒有匹配。如果右表中沒有匹配,則結果為 NULL。

語法

SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;
-- 或:
SELECT column_name(s)
FROM table1
LEFT OUTER JOIN table2
ON table1.column_name=table2.column_name;

4.4RIGHT JOIN : 右連線

RIGHT JOIN 關鍵字從右表(table2)返回所有的行,即使左表(table1)中沒有匹配。如果左表中沒有匹配,則結果為 NULL。

語法

SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name=table2.column_name;
-- 或:
SELECT column_name(s)
FROM table1
RIGHT OUTER JOIN table2
ON table1.column_name=table2.column_name;

4.5FULL JOIN : 全連線

  • FULL JOIN 的連線方式是隻要左表(table1)和右表(table2)其中一個表中存在匹配,則返回行。相當於結合了 LEFT JOIN 和 RIGHT JOIN 的結果。
  • ==特別注意: MySQL 並不支援 full join==
  • 語法
SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;

4.6子查詢

查詢的語句中還有一個查詢

select name from student where id in (select id from score where math > 10);

5.視圖表

5.1視圖表的特點

  • 檢視是資料的特定子集,是從其他表裡提取出資料而形成的虛擬表,或者說臨時表。
  • 建立視圖表依賴一個查詢。
  • 檢視是永遠不會自己消失的除非手動刪除它。
  • 檢視有時會對提高效率有幫助。臨時表不會對效能有幫助,是資源消耗者。
  • 檢視一般隨該資料庫存放在一起,臨時表永遠都是在 tempdb 裡的。
  • 檢視適合於多表連線瀏覽時使用;不適合增、刪、改,這樣可以提高執行效率。
  • 一般視圖表的名稱以 v_ 為字首,用來與正常表進行區分。
  • 對原表的修改會影響到檢視中的資料。

5.2建立檢視

  • 語法: create view 檢視名 as 查詢語句
  • 示例:
create view v_user_score as
select a.id, a.name, b.math, b.english
from student a inner join score b on a.id=b order by id;
-- 查詢
select * from v_user_score;
-- 刪除
drop view v_user_score;