1. 语言背景
不是一种完整地编程语言,而是数据子语言。只包括用来处理和创建数据库数据和元数据的语句。
SQL语句分为两类;
数据定义语言(DDL):用来创建表、联系和其他结构
数据操作语言(DML):用来查询、插入、修改和删除数据
2. SECLECT/FROM/WHERE结构
SELECT 字句指定哪些列将在查询结果集中列出
FROM 子句指定将从哪些表进行查询
WHERE 子句指定哪些行将在查询结果集中列出
2.1 单一表读取特定的列
SELECT Department, Buyer
FROM Sku_Data;
这样抽取的数据可能会出现一些行是重复的情况,可使用关键字DISTINCT来消除重复:
SELECT DISTINCT Department, Buyer
FROM Sku_Data;
若要查看SKU_DATA表的所有列,可以使用一个*来表示所有列都被显示:
SELECT *
FROM Sku_Data;
2.2单一表读取特定的行
SELECT *
FROM Sku_Data
WHERE Department = 'Water Sports'
SQL WHERE子句中,如果列包含字符或是日期类型,用于比较的值必须以单引号(’ ‘)引起来。如果这个列包含的是数字类型数据,则比较的值不需要在引号内。
2.3 单一表读取特定的行和列
SELECT DISTINCT Department, Buyer
FROM Sku_Data
WHERE Department = 'Climbing'
SQL不需要在WHERE子句中使用的列也出现在SELECT的列名列表中。
2.4 查询单个表的SQL
2.4.1 将结果排序
SELECT *
FROM ORDER_ITEM
ORDER BY OrderNember;
默认是递增(升序)的排序。通过添加第二个列名,可实现多条件排序。
SELECT *
FROM ORDER_ITEM
ORDER BY OrderNember, Price;
如果要降序排列,在列名后面添加SQL关键字DESC。
因此,若首先按照Price降序排列,再按照OrderNumber升序排列,可以指定:
SELECT *
FROM ORDER_ITEM
ORDER BY Price DESC, OrderNember ASC;
由于默认是升序,所以最后的ASC我们可以不指定。
2.4.2 SQL WHERE子句选项
复合WHERE子句
WHERE子句可以使用AND, OR, IN 和 NOT IN 运算符来包含多个条件
– AND操作符例子:选择SKU_DATA所有部门名称为Water Sports, 买主为Nancy Meyers的行:
SELECT *
FROM SKU_DATA
WHERE Department ='Camping'
AND Buyer = 'Nancy Meyers';
– OR操作符的使用
SELECT *
FROM SKU_DATA
WHERE Department ='Camping'
OR Department ='Climbing';
– IN操作符的使用
SELECT *
FROM SKU_DATA
WHERE Buyer IN ('Nancy Meyers, 'Cindo Lo', 'Jerry Martin' );
– NOT IN
SELECT *
FROM SKU_DATA
WHERE Buyer NOT IN ('Nancy Meyers, 'Cindo Lo', 'Jerry Martin' );
- WHERE子句的范围
– 可以使用 BETWEEN 关键字来指定数据值的范围。
SELECT *
FROM ORDER_ITEM
WHERE ExtendedPrice BETWEEN 100 AND 200;
相当于:
SELECT *
FROM ORDER_ITEM
WHERE ExtendedPrice >= 100
AND ExtendedPrice <= 200;
- WHERE子句中的通配符
– 可以使用 LIKE 来指定对于列值的部分匹配。
例如,在SKU_DATA表中寻找所有买主名为Pete的行。
SELECT *
FROM ORDER_ITEM
WHERE Buyer LIKE 'Pete%';
当百分号(%)作为通配符时,他代表着字符的任意顺序。”Pete%”意味着任何以字母Pete开头的字符序列。
可是,如果要统计SKU列编码中右侧开始第三个位置为2的编码,是否可以这样:
SELECT *
FROM ORDER_ITEM
WHERE SKU LIKE '%2%';
这样的话,开头或结尾是2的都有可能统计进去,所以应该用下面的方式:
SELECT *
FROM ORDER_ITEM
WHERE SKU LIKE '%2__';
应使用SQL下划线(_)字符来表示单个不确定的字符。
2.4.3 WHERE 和 ORDER语句的结合
SELECT *
FROM ORDER_ITEM
WHERE ExtendedPrice BETWEEN 100 AND 200
ORDER BY OrderNumber DESC;
2.5 在SQL查询中进行计算
2.5.1 使用内建函数
- 五个内置函数:SUM、AVG、 MIN、 MAX、 COUNT
–假设要知道RETAIL_ORDER表中所有订单的OrderTotal之和:
SELECT SUM(OrderTotal)
FROM RETAIL_ORDER;
上面算出的表只包含一个单元,默认列命名为”No Column name”,我们可以用如下的改进方法来给此列取名:
SELECT SUM(OrderTotal) AS OrderSum
FROM RETAIL_ORDER;
– 其中AS关键字为其设置一个列名
将内置函数用于WHERE子句,可增强其效用。
SELECT SUM(ExtendedPrice) AS Order3000Sum
FROM ORDER_ITEM
WHERE OrderNumber = 3000;
注意: SQL语句中的相等判断是一个”=”
SQL内置函数可以在一个语句中混合和匹配。
SELECT SUM(ExtendedPrice) AS OrderItemSum
AVG(ExtendedPrice) AS OrderItemAvg
MIN(ExtendedPrice) AS OrderItemMin
FROM ORDER_ITEM;
– COUNT 和 SUM函数类似,但COUNT计算行的数目,而SUM累加列的值
SELECT COUNT(*) AS NumofRows
FROM ORDER_ITEM;
以上语句是统计ORDER_ITEM这个表中所有的行数。注意,(*)必须要加上。
或者,假如要计算SKU_DATA表中不同Department的数目:
SELECT COUNT(Department) AS DeptCount
FROM SKU_DATA;
上式只计算了所有行的数目,我们要考虑是不是存在重复行的情况,所以要用如下查询:
SELECT COUNT(DISTINCT Department) AS DeptCount
FROM SKU_DATA;
- 内置函数是用的注意事项:
– 1. 除了分组(后面会讲),不能把SQL的内置函数和表列名结合在一起。
SELECT Department, COUNT(*)
FROM SKU_DATA;
– 2.内置函数不能放在WHERE子句中
2.5.2 SELECT语句中的表达式
– 使用表达式Quantity * Price来计算总价:
SELECT Quantity * Price AS EP, ExtendedPrice
FROM ORDER_ITEM;
– 还可以进行字符串操作,假设将Buyer和Department列结合成一个单一的名为Sponsor的列。
SELECT Buyer + ' in ' + Department AS Sponsor
FROM SKU_DATA;
这样虽然可以生成表,但是表中每一行可能含大部分空白,在SQL Server中,可用如下语句:
SELECT DISTINCT RTRIM(Buyer) + ' in ' + RTRIM(Department) AS Sponsor
FROM SKU_DATA;
2.6 SELECT 语句中的分组
- GROUP BY 关键字可以把值相同的行分组(貌似类似于Python中的字典)。
SELECT Department, COUNT(*) AS Dept_SKU_Count
FROM SKU_DATA
GROUP BY Department;
上面语句中,DBMS首先依照部门的值对行进行排序,然后计算相同部门值的行数。
SELECT SKU, AVG(EXtendPrice) AS AVGEP
FROM ORDER_ITEM
GROUP BY SKU;
这里行按照SKU进行排序和分组,然后计算每组SKU物品的平均ExtendedPrice。
- 注意:当使用GROUP BY子句时,只有在GROUP BY表达式中出现的列和SQL的内置函数可以被应用于SELECT子句中的表达式,下面语句会出错:
SELECT SKU, Department, COUNT(*) AS Dept_SKU_Count
FROM SKU_DATA
GROUP BY Department;
改为以下形式才正确:
SELECT SKU, Department, COUNT(*) AS Dept_SKU_Count
FROM SKU_DATA
GROUP BY SKU, Department;
表示先按SKU, 再按Department排序,然后计算这两个组合所对应的行数。
下面是个语句组合使用的例子:
SELECT Department, COUNT(*) AS Dept_SKU_Count
FROM SKU_DATA
WHERE SKU <>3020000
GROUP BY Department
HAVING COUNT (*) > 1
ORDER BY Dept_SKU_Count;
–其中HAVING子句限制在结果中出现的组。这句的作用是限制前面的查询,只显示包含有超过一行的组。
整体意思是:先按Department排序,抽取每个Department的个数,然后在这里面提取SKU != 3020000的行,只显示超过一行的组,最后按Dept_SKU_Count排序。
2.7 使用SQL查询两个或多个表
2.7.1 使用子查询(嵌套)
2.7.2 使用联接
参考文献
- 数据库处理(第十一版)