SQL單表查詢 一、單表查詢的語法 select列名1,列名2... from 表名 where 條件 group by field having 篩選 order by field limit 限制條數 二、關鍵字的執行優先順序 from where group by having select d ...
SQL單表查詢
一、單表查詢的語法
select列名1,列名2... from 表名
where 條件
group by field
having 篩選
order by field
limit 限制條數
二、關鍵字的執行優先順序
from
where
group by
having
select
distinct
order by
limit
1.找到表:from
2.where指定的約束條件
3.將取出的一條條記錄進行分組group by,如果沒有group by,則整體作為一組
4.將分組的結果進行having過濾
5.執行select
6.distinct去重
7.將結果按條件排序:order by
8.limit限制結果的顯示條數
三、select 語句
3.1查詢全部的列
select * from<表名>;
3.2為列設置別名
別名可以使用中文,使用中文時需要用雙引號(")括起來。請註意
不是單引號(')
3.3常數的查詢
SELECT '商品' AS string, 38 AS number, '2009-02-24' AS date,
product_id, product_name
FROM Product;
執行結果
string | number | date | product_id | product_name
---------+-----------+--------------+-------------+--------------
商品 | 38 | 2009-02-24 | 0001 | T恤衫
商品 | 38 | 2009-02-24 | 0002 | 打孔器
商品 | 38 | 2009-02-24 | 0003 | 運動T恤
商品 | 38 | 2009-02-24 | 0004 | 菜刀
商品 | 38 | 2009-02-24 | 0005 | 高壓鍋
商品 | 38 | 2009-02-24 | 0006 | 叉子
商品 | 38 | 2009-02-24 | 0007 | 擦菜板
商品 | 38 | 2009-02-24 | 0008 | 圓珠筆
如上述執行結果所示,所有的行中都顯示出了SELECT 子句中的常數。
3.4去重
1.語法:SELECT DISTINCT product_type FROM Product;
2.**DISTINCT 關鍵字只能用在第一個列名之前**
錯誤:regist_date, DISTINCT product_type。
3.如果多個數據為null,也會合併成一個。
3.5where語句
where子句要緊跟在from子句之後。
首先通過where 子句查詢出符合指定條件的記錄,然後再選取出select語句指
定的列。
四、算數運算、比較運算和邏輯運算
1.例子SELECT product_name, sale_price,sale_price * 2 AS "sale_price_x2"FROM Product;
2.包含NULL 的計算,結果是NULL
3.不等號為<>
4.字元串類型的數據原則上按照字典順序進行排序,不能與數字的大小順序混淆。例如'10' 和'11' 同樣都是以'1' 開頭的字元串,判定為比'2' 小
5.不能對NULL使用比較運算符(=、<>、>、<、>=、<=)例如:...where purchase_price = NULL,是查詢不到數據的,可以使用IS NULL,反之,希望選取不是NULL 的記錄時,需要使用IS NOT NULL
6.AND運算符的優先順序高於OR運算符,想要優先執行OR運算符時可以使用括弧。
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = '辦公用品'
AND regist_date = '2009-09-11'
OR regist_date = '2009-09-20';
執行結果
product_name | product_type | regist_date
---------------+--------------+------------
T恤衫 | 衣服 | 2009-09-20
打孔器 | 辦公用品 | 2009-09-11
菜刀 | 廚房用具 | 2009-09-20
叉子 | 廚房用具 | 2009-09-20
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = '辦公用品'
AND ( regist_date = '2009-09-11'
OR regist_date = '2009-09-20');
product_name | product_type | regist_date
---------------+--------------+------------
打孔器 | 辦公用品 | 2009-09-11
這樣就選取出了想要得到的“打孔器”。
法則
五、SQL中常用的聚合函數
sum()求和 count()計數 max()最大值 min()最小值 avg()平均值
3.1 **聚合函數會將null排除在外。但count(*)例外,並不會排除null。**
3.2 count函數的結果根據參數的不同而不同。count*)會得到包含NULL的數據
行數,而count(<列名>)會得到null之外的數據行數。
3.3 在聚合函數的參數中使用distinct,可以刪除重覆數據。例如sum(distinct 列名
六、group by語句
1.在group by 子句中指定的列稱為聚合鍵或者分組列。
2.聚合鍵中包含null時,在結果中會以“不確定”行(空行)的形式表現出來
3.where子句時group by的執行結果,會先根據where子句指定的條件進行過濾,然後再進行聚合。
聚合函數和GROUP BY子句有關常見錯誤
錯誤一:在SELECT子句中書寫了多餘的列(聚合鍵之外的列名書寫在SELECT 子句之中)
在使用COUNT 這樣的聚合函數時,SELECT 子句中的元素有嚴格的限制。實際上,使用聚合函數時,SELECT 子句中只能存在以下三種
元素。
● 常數
● 聚合函數
● GROUP BY子句中指定的列名(也就是聚合鍵)
如果需要聚合鍵之外的列,使用group_concat(列名)
錯誤二:在WHERE子句中使用聚合函數
七、註釋
● 單行註釋
書寫在“--”之後,只能寫在同一行。
● 多行註釋
書寫在“/”和“/”之間,可以跨多行。
八、代碼演示
create table class1_score(id int primary key auto_increment,name char(10),gender enum('男','女'),math int default 0,eng int default 0)
insert into class1_score(id,name,gender,math,eng) values
(1,'趙藝','女',85,88),
(2,'錢爾','女',85,90),
(3,'孫散','男',90,90),
(4,'李思','男',80,85),
(5,'周武','男',80,85),
(6,'吳流','女',90,90),
(7,'鄭其','男',70,75),
(8,'王','男',70,75),
(9,'馮九','男',95,85),
(10,'陳時','男',60,60);
mysql> select * from class1_score;
+----+--------+--------+------+------+
| id | name | gender | math | eng |
+----+--------+--------+------+------+
| 1 | 趙藝 | 女 | 85 | 88 |
| 2 | 錢爾 | 女 | 85 | 90 |
| 3 | 孫散 | 男 | 90 | 90 |
| 4 | 李思 | 男 | 80 | 85 |
| 5 | 周武 | 男 | 80 | 85 |
| 6 | 吳流 | 女 | 90 | 90 |
| 7 | 鄭其 | 男 | 70 | 75 |
| 8 | 王 | 男 | 70 | 75 |
| 9 | 馮九 | 男 | 95 | 85 |
| 10 | 陳時 | 男 | 60 | 60 |
+----+--------+--------+------+------+
10 rows in set (0.00 sec)
mysql> select * from class1_score where gender='男';
+----+--------+--------+------+------+
| id | name | gender | math | eng |
+----+--------+--------+------+------+
| 3 | 孫散 | 男 | 90 | 90 |
| 4 | 李思 | 男 | 80 | 85 |
| 5 | 周武 | 男 | 80 | 85 |
| 7 | 鄭其 | 男 | 70 | 75 |
| 8 | 王 | 男 | 70 | 75 |
| 9 | 馮九 | 男 | 95 | 85 |
| 10 | 陳時 | 男 | 60 | 60 |
+----+--------+--------+------+------+
7 rows in set (0.00 sec)
mysql> select name,math,eng from class1_score where math>89 and eng> 89;
+--------+------+------+
| name | math | eng |
+--------+------+------+
| 孫散 | 90 | 90 |
| 吳流 | 90 | 90 |
+--------+------+------+
2 rows in set (0.00 sec)
mysql> select * from class1_score where gender='男' having math>70;
+----+--------+--------+------+------+
| id | name | gender | math | eng |
+----+--------+--------+------+------+
| 3 | 孫散 | 男 | 90 | 90 |
| 4 | 李思 | 男 | 80 | 85 |
| 5 | 周武 | 男 | 80 | 85 |
| 9 | 馮九 | 男 | 95 | 85 |
+----+--------+--------+------+------+
4 rows in set (0.00 sec)
#選擇性別,根據性別進行分組
mysql> select gender from class1_score group by gender;
+--------+
| gender |
+--------+
| 男 |
| 女 |
+--------+
2 rows in set (0.00 sec)
mysql> select name,math from class1_score where math between 80 and 90;
+--------+------+
| name | math |
+--------+------+
| 趙藝 | 85 |
| 錢爾 | 85 |
| 孫散 | 90 |
| 李思 | 80 |
| 周武 | 80 |
| 吳流 | 90 |
+--------+------+
6 rows in set (0.00 sec)
#通配符%與_
#%代指不定位,_代指一個字元。
mysql> insert into class1_score values(11,'趙伊伊','女',85,88),(12,'趙十二','女',85,88);
mysql> select * from class1_score;
+----+-----------+--------+------+------+
| id | name | gender | math | eng |
+----+-----------+--------+------+------+
| 1 | 趙藝 | 女 | 85 | 88 |
| 2 | 錢爾 | 女 | 85 | 90 |
| 3 | 孫散 | 男 | 90 | 90 |
| 4 | 李思 | 男 | 80 | 85 |
| 5 | 周武 | 男 | 80 | 85 |
| 6 | 吳流 | 女 | 90 | 90 |
| 7 | 鄭其 | 男 | 70 | 75 |
| 8 | 王 | 男 | 70 | 75 |
| 9 | 馮九 | 男 | 95 | 85 |
| 10 | 陳時 | 男 | 60 | 60 |
| 11 | 趙伊伊 | 女 | 85 | 88 |
| 12 | 趙十二 | 女 | 85 | 88 |
| 13 | 趙十三 | 男 | 82 | 88 |
| 14 | 趙十思 | 女 | 85 | 85 |
+----+-----------+--------+------+------+
14 rows in set (0.00 sec)
mysql> select * from class1_score where name like '趙%';
+----+-----------+--------+------+------+
| id | name | gender | math | eng |
+----+-----------+--------+------+------+
| 1 | 趙藝 | 女 | 85 | 88 |
| 11 | 趙伊伊 | 女 | 85 | 88 |
| 12 | 趙十二 | 女 | 85 | 88 |
+----+-----------+--------+------+------+
mysql> select * from class1_score where name like '_思'; ,85,85)
+----+--------+--------+------+------+
| id | name | gender | math | eng |
+----+--------+--------+------+------+
| 4 | 李思 | 男 | 80 | 85 |
+----+--------+--------+------+------+
1 row in set (0.00 sec)
#查詢分組(按性別分組)中人數
mysql> select count(1),gender from class1_score group by gender;
# select count(1) as '男/女人數' ,gender from class1_score group by gender;
+----------+--------+
| count(1) | gender |
+----------+--------+
| 8 | 男 |
| 6 | 女 |
+----------+--------+
2 rows in set (0.00 sec)
#查詢並計算男生、女生數學總分
mysql> select sum(math),gender from class1_score group by gender;
+-----------+--------+
| sum(math) | gender |
+-----------+--------+
| 627 | 男 |
| 515 | 女 |
+-----------+--------+
2 rows in set (0.00 sec)
#查詢男生、女生英語最高分。
mysql> select max(eng),gender from class1_score group by gender;
+----------+--------+
| max(eng) | gender |
+----------+--------+
| 90 | 男 |
| 90 | 女 |
+----------+--------+
2 rows in set (0.00 sec)
#求男女生數學平均值
mysql> select avg(math),gender from class1_score group by gender;
+-----------+--------+
| avg(math) | gender |
+-----------+--------+
| 78.3750 | 男 |
| 85.8333 | 女 |
+-----------+--------+
2 rows in set (0.00 sec)
#group by 與 having聯用時,having 後的欄位要與group by相同
#如果想按性別分,並查看名字,下麵會出錯,因為按性別劃分後只有性別欄位
mysql>select name,gender from class1_score group by gender;
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'db1.class1_score.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
# group_concat
mysql> select group_concat(name),gender from class1_score group by gender;
+---------------------------------------------------------+--------+
| group_concat(name) | gender |
+---------------------------------------------------------+--------+
| 孫散,李思,周武,鄭其,王,馮九,陳時,趙十三 | 男 |
| 趙藝,錢爾,吳流,趙伊伊,趙十二,趙十思 | 女 |
+---------------------------------------------------------+--------+
2 rows in set (0.00 sec)
#查詢名字和數學成績並按數學成績升序
mysql> select name,math from class1_score order by math;
+-----------+------+
| name | math |
+-----------+------+
| 陳時 | 60 |
| 鄭其 | 70 |
| 王 | 70 |
| 李思 | 80 |
| 周武 | 80 |
| 趙十三 | 82 |
| 趙藝 | 85 |
| 錢爾 | 85 |
| 趙伊伊 | 85 |
| 趙十二 | 85 |
| 趙十思 | 85 |
| 孫散 | 90 |
| 吳流 | 90 |
| 馮九 | 95 |
+-----------+------+
14 rows in set (0.00 sec)
#數學升序(asc),英語降序(desc)
#排序鍵中包含NULL時,會在開頭或末尾進行彙總。
mysql> select name,math,eng from class1_score order by math asc,eng desc;
+-----------+------+------+
| name | math | eng |
+-----------+------+------+
| 陳時 | 60 | 60 |
| 鄭其 | 70 | 75 |
| 王 | 70 | 75 |
| 李思 | 80 | 85 |
| 周武 | 80 | 85 |
| 趙十三 | 82 | 88 |
| 錢爾 | 85 | 90 |
| 趙藝 | 85 | 88 |
| 趙伊伊 | 85 | 88 |
| 趙十二 | 85 | 88 |
| 趙十思 | 85 | 85 |
| 孫散 | 90 | 90 |
| 吳流 | 90 | 90 |
| 馮九 | 95 | 85 |
+-----------+------+------+
14 rows in set (0.00 sec)
#數學前三(limit 起始位置,獲取個數 可用於分頁 索引類似,從0開始)
mysql> select name,math from class1_score order by math desc limit 0,3;
+--------+------+
| name | math |
+--------+------+
| 馮九 | 95 |
| 孫散 | 90 |
| 吳流 | 90 |
+--------+------+
3 rows in set (0.00 sec)