本文所用数据来源:
https://bbs.fanruan.com/ueditor/php/upload/file/20190610/1560156571373194.zip
SQL SELECT语句
- SELECT 语句用于从数据库中选取数据。结果被存储在一个结果表中,称为结果集。
用法:
SELECT column_name FROM table_name
例:
SELECT `订单ID`,`客户ID` FROM `订单`
SQL SELECT DISTINCT 语句
- 在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。
DISTINCT 关键词用于返回唯一不同的值。
用法:
SELECT DISTINCT column_name,column_name
FROM table_name
例:
SELECT DISTINCT`货主地区` FROM `订单`
SQL WHERE 子句
- WHERE 子句用于提取那些满足指定条件的记录。
用法:
SELECT column_name,column_name
FROM table_name
WHERE column_name operator value
例:
SELECT `订单ID`,`雇员ID` FROM `订单`
WHERE `雇员ID`= '1'
SQL AND & OR 运算符
- 如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。
如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。
例:
SELECT `订单ID`,`雇员ID`,`货主地区` FROM `订单`
WHERE `雇员ID`= '1'
AND `货主地区`= '华东'
SQL BETWEEN 操作符
- BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
用法:
SELECT column_name(s)
FROM table_name
WHERE column_name BETWEEN value1 AND value2
例:
SELECT 订购日期,订单ID,客户ID FROM 订单
WHERE 订购日期 BETWEEN '1996-07-01' AND '1996-07-15'
SELECT `产品ID`,`产品名称`,`库存量`
FROM `产品`
WHERE `单价`BETWEEN '10' AND '30'
SQL 连接(JOIN)
- SQL JOIN 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。
- INNER JOIN:如果表中有至少一个匹配,则返回行
LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行
RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行
FULL JOIN:只要其中一个表中存在匹配,则返回行
LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。
用法:
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name
例:
SELECT * FROM `订单`
LEFT JOIN `订单明细`
ON `订单`.`订单ID` = `订单明细`.`订单ID`
RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配。如果左表中没有匹配,则结果为 NULL。
用法:
SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name=table2.column_name
SQL UNION 操作符
- UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。
用法:
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2
例:
SELECT `货主地区` FROM `订单`
UNION
SELECT `地区` FROM `客户`
注释1:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
注释2:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL函数
- SQL 拥有很多可用于计数和计算的内建函数。
SQL Aggregate 函数计算从列中取得的值,返回一个单一的值。
- AVG() – 返回数值列的平均值。
COUNT() – 返回匹配指定条件的行数。
FIRST() – 返回指定的列中第一个记录的值。
LAST() – 返回指定的列中最后一个记录的值。(注释:只有 MS Access 支持 LAST() 函数。)
MAX() – 返回指定列的最大值。
MIN() – 返回指定列的最小值。
SUM() – 返回数值列的总数。
SELECT AVG(column_name) FROM table_name
SELECT COUNT(column_name) FROM table_name
SELECT FIRST(column_name) FROM table_name
SELECT LAST(column_name) FROM table_name
SELECT MAX(column_name) FROM table_name
SELECT MIN(column_name) FROM table_name
SELECT SUM(column_name) FROM table_name
SQL Scalar 函数基于输入值,返回一个单一的值。
- UCASE() – 将某个字段转换为大写
LCASE() – 将某个字段转换为小写
MID() – 从某个文本字段提取字符,MySql 中使用
SubString(字段,1,end) – 从某个文本字段提取字符
LEN() – 返回某个文本字段的长度
ROUND() – 对某个数值字段进行指定小数位数的四舍五入
NOW() – 返回当前的系统日期和时间
FORMAT() – 格式化某个字段的显示方式
其他方法详见 https://www.shulanxt.com/database/sql/sql-tutorial
SQL练习题:
单表查询
1、查询订购日期在1996年7月1日至1996年7月15日之间的订单的订购日期、订单ID、客户ID和雇员ID等字段的值。
SELECT 订购日期,订单ID,客户ID,雇员ID FROM 订单
WHERE 订购日期 BETWEEN '1996-07-01' AND '1996-07-15'
2、查询供应商的ID、公司名称、地区、城市和电话字段的值。条件是“地区等于华北”并且“联系人头衔等于销售代表”。
SELECT `供应商ID`,`公司名称`,`地区`,`城市`,`电话` FROM `供应商`
WHERE `地区`='华北' AND `联系人职务`='销售代表'
3、查询供应商的ID、公司名称、地区、城市和电话字段的值。其中的一些供应商位于华东或华南地区,另外一些供应商所在的城市是天津。
SELECT `供应商ID`,`公司名称`,`地区`,`城市`,`电话` FROM `供应商`
WHERE (`地区`='华东' OR `地区`='华南')
OR `城市`='天津'
4、查询位于“华东”或“华南”地区的供应商的ID、公司名称、地区、城市和电话字段的值。
SELECT `供应商ID`,`公司名称`,`地区`,`城市`,`电话` FROM `供应商`
WHERE (`地区`='华东' OR `地区`='华南')
多表查询
5、查询订购日期在1996年7月1日至1996年7月15日之间的订单的订购日期、订单ID、相应订单的客户公司名称、负责订单的雇员的姓氏和名字等字段的值,并将查询结果按雇员的“姓氏”和“名字”字段的升序排列,“姓氏”和“名字”值相同的记录按“订单 ID”的降序排列。
SELECT `订购日期`,`订单ID`,`公司名称`,`姓氏`,`名字`
FROM `订单`,`客户`,`雇员`
WHERE `订单`.`客户ID`=`客户`.`客户ID`
AND `订单`.`雇员ID`=`雇员`.`雇员ID`
AND `订单`.`订购日期` BETWEEN '1996-07-01' AND '1996-07-15'
ORDER BY CONVERT(`姓氏` USING gbk), CONVERT(`名字` USING gbk), CONVERT(`订单ID` USING gbk)DESC
注释:由于原姓氏、名字字段的排序规则为utf-8,无法正确排序,所以这里进行字符集转换gbk,用法为 CONVERT(…USING…)
6、查询“10248”和“10254”号订单的订单ID、运货商的公司名称、订单上所订购的产品的名称。
SELECT `订单`.`订单ID`,`公司名称`,`产品名称`
FROM `订单`
LEFT JOIN `运货商`
ON `订单`.`运货商`=`运货商`.`运货商ID`
LEFT JOIN `订单明细`
ON `订单`.`订单ID`=`订单明细`.`订单ID`
LEFT JOIN `产品`
ON `订单明细`.`产品ID`=`产品`.`产品ID`
WHERE `订单`.`订单ID`IN (10248,10254)
7、查询“10248”和“10254”号订单的订单ID、订单上所订购的产品的名称、数量、单价和折扣。
SELECT `订单`.`订单ID`,`产品名称`,`数量`,`订单明细`.`单价`,`折扣`
FROM `订单`
LEFT JOIN `订单明细`
ON `订单`.`订单ID`=`订单明细`.`订单ID`
LEFT JOIN `产品`
ON `产品`.`产品ID`=`订单明细`.`产品ID`
WHERE `订单明细`.`订单ID` IN (10248,10254)
8、查询“10248”和“10254”号订单的订单ID、订单上所订购的产品的名称及其销售金额。
SELECT `订单`.`订单ID`,`产品名称`,ROUND(`订单明细`.`数量` * `订单明细`.`单价` * (1-`折扣`),2) AS `销售金额`
FROM `订单`
LEFT JOIN `订单明细`
ON `订单`.`订单ID`=`订单明细`.`订单ID`
LEFT JOIN `产品`
ON `订单明细`.`产品ID`=`产品`.`产品ID`
WHERE `订单`.`订单ID` IN (10248,10254)
注释:保留两位小数
综合查询
9、查询所有运货商的公司名称和电话。
SELECT `公司名称`,`电话` FROM `运货商`
10、查询所有客户的公司名称、电话、传真、地址、联系人姓名和联系人头衔。
SELECT `公司名称`,`电话`,`传真`,`地址`,`联系人姓名`, `联系人职务`
FROM `客户`
11、查询单价介于10至30元的所有产品的产品ID、产品名称和库存量
SELECT `产品ID`,`产品名称`,`库存量`
FROM `产品`
WHERE `单价`BETWEEN '10' AND '30'
12、查询单价大于20元的所有产品的产品名称、单价以及供应商的公司名称、电话
SELECT `产品名称`,`单价`,`公司名称`,`电话`
FROM `产品`
LEFT JOIN `供应商`
ON `产品`.`供应商ID`=`供应商`.`供应商ID`
WHERE `单价`>'20'
13、查询上海和北京的客户在1996年订购的所有订单的订单ID、所订购的产品名称和数量
SELECT `订单`.`订单ID`,`产品名称`,`数量`
FROM `订单`
LEFT JOIN `订单明细`
ON `订单`.`订单ID`=`订单明细`.`订单ID`
LEFT JOIN `产品`
ON `订单明细`.`产品ID`=`产品`.`产品ID`
LEFT JOIN `客户`
ON `订单`.`客户ID`=`客户`.`客户ID`
WHERE YEAR(`订单`.`订购日期`) = '1996'
AND `客户`.`城市` IN ('上海','北京')
14、查询华北客户的每份订单的订单ID、产品名称和销售金额
SELECT `订单`.`订单ID`,`产品名称`,ROUND(`订单明细`.`单价`*`订单明细`.`数量`*(1-`折扣`),2) AS `销售金额`
FROM `订单`
LEFT JOIN `订单明细`
ON `订单`.`订单ID`=`订单明细`.`订单ID`
LEFT JOIN `产品`
ON `订单明细`.`产品ID`=`产品`.`产品ID`
LEFT JOIN `客户`
ON `订单`.`客户ID`=`客户`.`客户ID`
WHERE 客户.`地区`='华北'
15、按运货商公司名称,统计1997年由各个运货商承运的订单的总数量
SELECT `运货商`.`公司名称`,COUNT(`订单`.`运货商`) AS `总数量`
FROM `订单`
LEFT JOIN `运货商` ON `订单`.`运货商`=`运货商`.`运货商ID`
WHERE YEAR(`订单`.`发货日期`) = '1997'
GROUP BY `公司名称`
16、统计1997年上半年的每份订单上所订购的产品的总数量
SELECT `订单`.`订单ID`,SUM(`订单明细`.`数量`) AS `总数量`
FROM `订单`
left JOIN `订单明细`
ON `订单明细`.`订单ID` = `订单`.`订单ID`
WHERE `订单`.`订购日期` BETWEEN '1997-01-01' AND '1997-07-01'
GROUP BY `订单ID`
17、统计各类产品的平均价格
SELECT `产品`.`类别ID`,ROUND(AVG(`产品`.`单价`),2) AS `平均价格`
FROM `产品`
GROUP BY `产品`.`类别ID`
18、统计各地区客户的总数量
SELECT `客户`.`地区`,COUNT(`客户`.`地区`) AS `客户总数量`
FROM `客户`
GROUP BY `客户`.`地区`
后续再更新。