第03章_基本的SELECT語句
第03章_基本的SELECT語句
1. SQL概述
1.1 SQL背景知識
-
1946 年,世界上第一台電腦誕生,如今,藉由這台電腦發展起來的互聯網已經自成江湖。在這幾十年里,無數的技術、產業在這片江湖裡沉浮,有的方興未艾,有的已經幾幕興衰。但在這片浩蕩的波動里,有一門技術從未消失,甚至「老當益壯」,那就是 SQL。
- 45 年前,也就是 1974 年,IBM 研究員發佈了一篇揭開數據庫技術的論文《SEQUEL:一門結構化的英語查詢語言》,直到今天這門結構化的查詢語言並沒有太大的變化,相比於其他語言,
SQL 的半衰期可以說是非常長
了。
- 45 年前,也就是 1974 年,IBM 研究員發佈了一篇揭開數據庫技術的論文《SEQUEL:一門結構化的英語查詢語言》,直到今天這門結構化的查詢語言並沒有太大的變化,相比於其他語言,
-
不論是前端工程師,還是後端算法工程師,都一定會和數據打交道,都需要了解如何又快又準確地提取自己想要的數據。更別提數據分析師了,他們的工作就是和數據打交道,整理不同的報告,以便指導業務決策。
-
SQL(Structured Query Language,結構化查詢語言)是使用關係模型的數據庫應用語言,
與數據直接打交道
,由IBM
上世紀70年代開發出來。後由美國國家標準局(ANSI)開始着手制定SQL標準,先後有SQL-86
,SQL-89
,SQL-92
,SQL-99
等標準。- SQL 有兩個重要的標準,分別是 SQL92 和 SQL99,它們分別代表了 92 年和 99 年頒佈的 SQL 標準,我們今天使用的 SQL 語言依然遵循這些標準。
-
不同的數據庫生產廠商都支持SQL語句,但都有特有內容。
1.2 SQL語言排行榜
自從 SQL 加入了 TIOBE 編程語言排行榜,就一直保持在 Top 10。
1.3 SQL 分類
SQL語言在功能上主要分為如下3大類:
-
DDL(Data Definition Languages、數據定義語言),這些語句定義了不同的數據庫、表、視圖、索引等數據庫對象,還可以用來創建、刪除、修改數據庫和數據表的結構。
- 主要的語句關鍵字包括
CREATE
、DROP
、ALTER
等。
- 主要的語句關鍵字包括
-
DML(Data Manipulation Language、數據操作語言),用於添加、刪除、更新和查詢數據庫記錄,並檢查數據完整性。
- 主要的語句關鍵字包括
INSERT
、DELETE
、UPDATE
、SELECT
等。 - SELECT是SQL語言的基礎,最為重要。
- 主要的語句關鍵字包括
-
DCL(Data Control Language、數據控制語言),用於定義數據庫、表、字段、用戶的訪問權限和安全級別。
- 主要的語句關鍵字包括
GRANT
、REVOKE
、COMMIT
、ROLLBACK
、SAVEPOINT
等。
- 主要的語句關鍵字包括
因為查詢語句使用的非常的頻繁,所以很多人把查詢語句單拎出來一類:DQL(數據查詢語言)。
還有單獨將
COMMIT
、ROLLBACK
取出來稱為TCL (Transaction Control Language,事務控制語言)。
2. SQL語言的規則與規範
2.1 基本規則
- SQL 可以寫在一行或者多行。為了提高可讀性,各子句分行寫,必要時使用縮進
- 每條命令以 ; 或 \g 或 \G 結束
- 關鍵字不能被縮寫也不能分行
- 關於標點符號
- 必須保證所有的()、單引號、雙引號是成對結束的
- 必須使用英文狀態下的半角輸入方式
- 字符串型和日期時間類型的數據可以使用單引號(’ ‘)表示
- 列的別名,盡量使用雙引號(” “),而且不建議省略as
2.2 SQL大小寫規範 (建議遵守)
- MySQL 在 Windows 環境下是大小寫不敏感的
- MySQL 在 Linux 環境下是大小寫敏感的
- 數據庫名、表名、表的別名、變量名是嚴格區分大小寫的
- 關鍵字、函數名、列名(或字段名)、列的別名(字段的別名) 是忽略大小寫的。
- 推薦採用統一的書寫規範:
- 數據庫名、表名、表別名、字段名、字段別名等都小寫
- SQL 關鍵字、函數名、綁定變量等都大寫
2.3 注 釋
可以使用如下格式的注釋結構
單行注釋:#注釋文字(MySQL特有的方式)
單行注釋:-- 注釋文字(--後面必須包含一個空格。)
多行注釋:/* 注釋文字 */
2.4 命名規則(暫時了解)
- 數據庫、表名不得超過30個字符,變量名限制為29個
- 必須只能包含 A–Z, a–z, 0–9, _共63個字符
- 數據庫名、表名、字段名等對象名中間不要包含空格
- 同一個MySQL軟件中,數據庫不能同名;同一個庫中,表不能重名;同一個表中,字段不能重名
- 必須保證你的字段沒有和保留字、數據庫系統或常用方法衝突。如果堅持使用,請在SQL語句中使用`(着重號)引起來
- 保持字段名和類型的一致性,在命名字段並為其指定數據類型的時候一定要保證一致性。假如數據類型在一個表裡是整數,那在另一個表裡可就別變成字符型了
舉例:
#以下兩句是一樣的,不區分大小寫
show databases;
SHOW DATABASES;
#創建表格
#create table student info(...); #表名錯誤,因為表名有空格
create table student_info(...);
#其中order使用``飄號,因為order和系統關鍵字或系統函數名等預定義標識符重名了
CREATE TABLE `order`(
id INT,
lname VARCHAR(20)
);
select id as "編號", `name` as "姓名" from t_stu; #起別名時,as都可以省略
select id as 編號, `name` as 姓名 from t_stu; #如果字段別名中沒有空格,那麼可以省略""
select id as 編 號, `name` as 姓 名 from t_stu; #錯誤,如果字段別名中有空格,那麼不能省略""
2.5 數據導入指令
在命令行客戶端登錄mysql,使用source指令導入
mysql> source d:\mysqldb.sql
mysql> desc employees;
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| employee_id | int(6) | NO | PRI | 0 | |
| first_name | varchar(20) | YES | | NULL | |
| last_name | varchar(25) | NO | | NULL | |
| email | varchar(25) | NO | UNI | NULL | |
| phone_number | varchar(20) | YES | | NULL | |
| hire_date | date | NO | | NULL | |
| job_id | varchar(10) | NO | MUL | NULL | |
| salary | double(8,2) | YES | | NULL | |
| commission_pct | double(2,2) | YES | | NULL | |
| manager_id | int(6) | YES | MUL | NULL | |
| department_id | int(4) | YES | MUL | NULL | |
+----------------+-------------+------+-----+---------+-------+
11 rows in set (0.00 sec)
3. 基本的SELECT語句
3.0 SELECT…
SELECT 1; #沒有任何子句
SELECT 9/2; #沒有任何子句
3.1 SELECT … FROM
- 語法:
SELECT 標識選擇哪些列
FROM 標識從哪個表中選擇
- 選擇全部列:
SELECT *
FROM departments;
一般情況下,除非需要使用表中所有的字段數據,最好不要使用通配符『*』。使用通配符雖然可以節省輸入查詢語句的時間,但是獲取不需要的列數據通常會降低查詢和所使用的應用程序的效率。通配符的優勢是,當不知道所需要的列的名稱時,可以通過它獲取它們。
在生產環境下,不推薦你直接使用
SELECT *
進行查詢。
- 選擇特定的列:
SELECT department_id, location_id
FROM departments;
MySQL中的SQL語句是不區分大小寫的,因此SELECT和select的作用是相同的,但是,許多開發人員習慣將關鍵字大寫、數據列和表名小寫,讀者也應該養成一個良好的編程習慣,這樣寫出來的代碼更容易閱讀和維護。
3.2 列的別名
-
重命名一個列
-
便於計算
-
緊跟列名,也可以在列名和別名之間加入關鍵字AS,別名使用雙引號,以便在別名中包含空格或特殊的字符並區分大小寫。
-
AS 可以省略
-
建議別名簡短,見名知意
-
舉例
SELECT last_name AS name, commission_pct comm FROM employees;
SELECT last_name "Name", salary*12 "Annual Salary" FROM employees;
3.3 去除重複行
默認情況下,查詢會返回全部行,包括重複行。
SELECT department_id
FROM employees;
在SELECT語句中使用關鍵字DISTINCT去除重複行
SELECT DISTINCT department_id
FROM employees;
針對於:
SELECT DISTINCT department_id,salary
FROM employees;
這裡有兩點需要注意:
- DISTINCT 需要放到所有列名的前面,如果寫成
SELECT salary, DISTINCT department_id FROM employees
會報錯。 - DISTINCT 其實是對後面所有列名的組合進行去重,你能看到最後的結果是 74 條,因為這 74 個部門id不同,都有 salary 這個屬性值。如果你想要看都有哪些不同的部門(department_id),只需要寫
DISTINCT department_id
即可,後面不需要再加其他的列名了。
3.4 空值參與運算
- 所有運算符或列值遇到null值,運算的結果都為null
SELECT employee_id,salary,commission_pct,
12 * salary * (1 + commission_pct) "annual_sal"
FROM employees;
這裡你一定要注意,在 MySQL 裏面, 空值不等於空字符串。一個空字符串的長度是 0,而一個空值的長度是空。而且,在 MySQL 裏面,空值是佔用空間的。
3.5 着重號
- 錯誤的
mysql> SELECT * FROM ORDER;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ORDER' at line 1
- 正確的
mysql> SELECT * FROM `ORDER`;
+----------+------------+
| order_id | order_name |
+----------+------------+
| 1 | shkstart |
| 2 | tomcat |
| 3 | dubbo |
+----------+------------+
3 rows in set (0.00 sec)
mysql> SELECT * FROM `order`;
+----------+------------+
| order_id | order_name |
+----------+------------+
| 1 | shkstart |
| 2 | tomcat |
| 3 | dubbo |
+----------+------------+
3 rows in set (0.00 sec)
- 結論
我們需要保證表中的字段、表名等沒有和保留字、數據庫系統或常用方法衝突。如果真的相同,請在SQL語句中使用一對“(着重號)引起來。
3.6 5、查詢常數
SELECT 查詢還可以對常數進行查詢。對的,就是在 SELECT 查詢結果中增加一列固定的常數列。這列的取值是我們指定的,而不是從數據表中動態取出的。
你可能會問為什麼我們還要對常數進行查詢呢?
SQL 中的 SELECT 語法的確提供了這個功能,一般來說我們只從一個表中查詢數據,通常不需要增加一個固定的常數列,但如果我們想整合不同的數據源,用常數列作為這個表的標記,就需要查詢常數。
比如說,我們想對 employees 數據表中的員工姓名進行查詢,同時增加一列字段corporation
,這個字段固定值為「尚硅谷」,可以這樣寫:
SELECT '尚硅谷' as corporation, last_name FROM employees;
4. 顯示錶結構
使用DESCRIBE 或 DESC 命令,表示表結構。
DESCRIBE employees;
或
DESC employees;
mysql> desc employees;
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| employee_id | int(6) | NO | PRI | 0 | |
| first_name | varchar(20) | YES | | NULL | |
| last_name | varchar(25) | NO | | NULL | |
| email | varchar(25) | NO | UNI | NULL | |
| phone_number | varchar(20) | YES | | NULL | |
| hire_date | date | NO | | NULL | |
| job_id | varchar(10) | NO | MUL | NULL | |
| salary | double(8,2) | YES | | NULL | |
| commission_pct | double(2,2) | YES | | NULL | |
| manager_id | int(6) | YES | MUL | NULL | |
| department_id | int(4) | YES | MUL | NULL | |
+----------------+-------------+------+-----+---------+-------+
11 rows in set (0.00 sec)
其中,各個字段的含義分別解釋如下:
- Field:表示字段名稱。
- Type:表示字段類型,這裡 barcode、goodsname 是文本型的,price 是整數類型的。
- Null:表示該列是否可以存儲NULL值。
- Key:表示該列是否已編製索引。PRI表示該列是表主鍵的一部分;UNI表示該列是UNIQUE索引的一部分;MUL表示在列中某個給定值允許出現多次。
- Default:表示該列是否有默認值,如果有,那麼值是多少。
- Extra:表示可以獲取的與給定列有關的附加信息,例如AUTO_INCREMENT等。
5. 過濾數據
- 背景:
-
語法:
SELECT 字段1,字段2 FROM 表名 WHERE 過濾條件
- 使用WHERE 子句,將不滿足條件的行過濾掉
- WHERE子句緊隨 FROM子句
-
舉例
SELECT employee_id, last_name, job_id, department_id
FROM employees
WHERE department_id = 90 ;