SQL 必知必会(第 4 版)--第7课-第12课

SQL 必知必会(第 4 版)(2013)

第七课 创建计算字段

  • 计算字段
    • 计算字段是运行时在 SELECT 语句内创建的。
    • 字段(field)基本上与列(column)的意思相同,经常互换使用,不过数据库列一般称为列,而术语字段通常与计算字段一起使用。
  • 拼接字段
    • +,||,Concat
    • 拼接(concatenate)将值联结到一起(将一个值附加到另一个值)构成单个值。
    • 用加号的例子:SELECT vend_name + ' (' + vend_country + ')' FROM Vendors ORDER BY vend_name;
    • SQL 支持列别名。别名(alias)是一个字段或值的替换名。别名用 AS 关键字赋予。
    • 在很多 DBMS 中,AS 关键字是可选的,不过最好使用它,这被视为一条最佳实践。
    • 别名他用途。常见包括在实际的表列名包含不合法的字符(如空格)时重新命名它,在原来的名字含混或容易误解时扩充它。
    • 别名的名字既可以是一个单词,也可以是一个字符串。如果是后者,字符串应该括在引号中。虽然这种做法是合法的,但不建议这么去做。
    • 别名有时也称为导出列(derived column)。
  • 执行算术计算
    • 计算字段的另一常见用途是对检索出的数据进行算术计算。SELECT prod_id, quantity, item_price, quantity*item_price AS expanded_price FROM OrderItems WHERE order_num = 20008;
    • 操作符:+,-,*,/,圆括号可用来区分优先顺序。

第八课 使用函数处理数据

  • 函数
    • SQL 也可以用函数来处理数据。函数一般是在数据上执行的,为数据的转换和处理提供了方便。
    • 每一个 DBMS 都有特定的函数。事实上,只有少数几个函数被所有主要的 DBMS 等同地支持。
    • 可移植(portable)所编写的代码可以在多个系统上运行。
  • 使用函数
    • 大多数SQL实现支持以下类型的函数。
      • 用于处理文本字符串(如删除或填充值,转换值为大写或小写)的文本函数。
      • 用于在数值数据上进行算术操作(如返回绝对值,进行代数运算)的数值函数。
      • 用于处理日期和时间值并从这些值中提取特定成分(如返回两个日期之差,检查日期有效性)的日期和时间函数。
      • 返回 DBMS 正使用的特殊信息(如返回用户登录信息)的系统函数。
    • 文本处理函数
      • SELECT vend_name, UPPER(vend_name) AS vend_name_upcase FROM Vendors ORDER BY vend_name;
      • LEFT()(或使用子字符串函数):返回字符串左边的字符
      • LENGTH()(也使用 DATALENGTH()或 LEN()):返回字符串的长度
      • LOWER()(Access使用 LCASE()):将字符串转为小写
      • LTRIM():去掉字符串左边的空格
      • RIGHT()(或使用子字符串函数):返回字符串右边的字符
      • RTRIM():去掉字符串右边的空格
      • SOUNDEX():返回字符串的 SOUNDEX 值
      • UPPER()(Access 使用 UCASE()):将字符串转换为大写
      • SOUNDEX 是一个将任何文本串转换为描述其语音表示的字母数字模式的算法。SOUNDEX 考虑了类似的发音字符和音节,使得能对字符串进行发音比较而不是字母比较。
    • 日期和时间处理函数
      • 期和时间采用相应的数据类型存储在表中,每种 DBMS 都有自己的特殊形式。很不一致,可移植性最差。
    • 数值处理函数
      • 数值处理函数仅处理数值数据。这些函数一般主要用于代数、三角或几何运算
        在主要DBMS的函数中,数值函数是最一致、最统一的函数
      • ABS():返回一个数的绝对值
      • COS():返回一个角度的余弦
      • EXP():返回一个数的指数值
      • PI():返回圆周率
      • SIN():返回一个角度的正弦
      • SQRT():返回一个数的平方根
      • TAN():返回一个角度的正切

第九课 汇总数据

  • 聚集函数
    • 聚集函数(aggregate function)对某些行运行的函数,计算并返回一个值。
    • AVG():返回某列的平均值
    • COUNT():返回某列的行数
    • MAX():返回某列的最大值
    • MIN():返回某列的最小值
    • SUM():返回某列值之和
    • AVG()函数
      • AVG()通过对表中行数计数并计算其列值之和,求得该列的平均值。AVG()可用来返回所有列的平均值,也可以用来返回特定列或行的平均值。
      • SELECT AVG(prod_price) AS avg_price FROM Products;
      • SELECT AVG(prod_price) AS avg_price FROM Products WHERE vend_id = 'DLL01';
      • AVG()只能用来确定特定数值列的平均值,而且列名必须作为函数参数给出。为了获得多个列的平均值,必须使用多个 AVG()函数。
      • AVG()函数忽略列值为 NULL 的行。
    • COUNT()函数
      • COUNT()函数进行计数。可利用 COUNT()确定表中行的数目或符合特定条件的行的数目。
      • COUNT()函数有两种使用方式:
        • 使用 COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。
        • 使用 COUNT(column)对特定列中具有值的行进行计数,忽略 NULL 值。
      • SELECT COUNT(*) AS num_cust FROM Customers;,不管行中各列有什么值。计数值在 num_cust 中返回。
      • 如果指定列名,则 COUNT()函数会忽略指定列的值为空的行,但如果 COUNT()函数中用的是星号(*),则不忽略。
    • MAX()函数
      • MAX()返回指定列中的最大值。MAX()要求指定列名
      • SELECT MAX(prod_price) AS max_price FROM Products;,MAX()返回 Products 表中最贵物品的价格。
      • MAX()函数忽略列值为 NULL 的行。
    • MIN()函数
      • 返回指定列的最小值。与 MAX()一样,MIN()要求指定列名,用法同 MAX()
    • SUM()函数
      • SUM()用来返回指定列值的和(总计)。
      • SELECT SUM(quantity) AS items_ordered FROM OrderItems WHERE order_num = 20005;
      • SUM()也可以用来合计计算值。
      • 利用标准的算术操作符,所有聚集函数都可用来执行多个列上的计算。SELECT SUM(item_price*quantity) AS total_price FROM OrderItems WHERE order_num = 20005;
      • SUM()函数忽略列值为NULL的行。
  • 聚集不同值
    • 以上 5 个聚集函数都可以如下使用。
      • 对所有行执行计算,指定 ALL 参数或不指定参数(因为 ALL 是默认行为)。
      • 只包含不同的值,指定 DISTINCT 参数。
    • ALL参数不需要指定,因为它是默认行为。如果不指定 DISTINCT,则假定为 ALL。
    • SELECT AVG(DISTINCT prod_price) AS avg_price FROM Products WHERE vend_id = 'DLL01';
    • 如果指定列名,则 DISTINCT 只能用于 COUNT()。DISTINCT 不能用于 COUNT(*)。类似地,DISTINCT 必须使用列名,不能用于计算或表达式。
    • 虽然 DISTINCT 从技术上可用于 MIN()和 MAX(),但这样做实际上没有价值。一个列中的最小值和最大值不管是否只考虑不同值,结果都是相同的。
  • 组合聚集函数
    • SELECT COUNT(*) AS num_items, MIN(prod_price) AS price_min, MAX(prod_price) AS price_max, AVG(prod_price) AS price_avg FROM Products;

第十课 分组数据

  • 数据分组
    • 使用分组可以将数据分为多个逻辑组,对每个组进行聚集计算。
  • 创建分组
    • 分组是使用 SELECT 语句的 GROUP BY 子句建立的。
    • SELECT vend_id, COUNT(*) AS num_prods FROM Products GROUP BY vend_id;
    • 因为使用了 GROUP BY,就不必指定要计算和估值的每个组了。系统会自动完成。GROUP BY 子句指示 DBMS 分组数据,然后对每个组而不是整个结果集进行聚集。
    • 使用 GROUP BY 子句前,需要知道一些重要的规定
      • GROUP BY 子句可以包含任意数目的列,因而可以对分组进行嵌套,更细致地进行数据分组。
      • 如果在 GROUP BY 子句中嵌套了分组,数据将在最后指定的分组上进行汇总。
      • GROUP BY 子句中列出的每一列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在 SELECT 中使用表达式,则必须在 GROUP BY 子句中指定相同的表达式。不能使用别名。
      • 大多数 SQL 实现不允许 GROUP BY 列带有长度可变的数据类型(如文本或备注型字段)。
      • 除聚集计算语句外,SELECT 语句中的每一列都必须在 GROUP BY 子句中给出。
      • 如果分组列中包含具有 NULL 值的行,则 NULL 将作为一个分组返回。如果列中有多行 NULL 值,它们将分为一组。
      • GROUP BY 子句必须出现在 WHERE 子句之后,ORDER BY 子句之前。
  • 过滤分组
    • 除了能用 GROUP BY 分组数据外,SQL 还允许过滤分组,规定包括哪些分组,排除哪些分组。
    • WHERE 过滤行,而 HAVING 过滤分组。
    • SELECT cust_id, COUNT(*) AS orders FROM Orders GROUP BY cust_id HAVING COUNT(*) >= 2;
    • 另一种理解方法,WHERE 在数据分组前进行过滤,HAVING 在数据分组后进行过滤。
    • 存在一条语句中同时使用 WHERE 和 HAVING 子句需求。
  • 分组和排序
    • GROUP BY 和 ORDER BY 经常完成相同的工作,但它们非常不同
    • GROUP BY 对产生的输出排序,ORDER BY 对行分组,但输出可能不是分组的顺序。
    • 一般在使用 GROUP BY 子句时,应该也给出 ORDER BY 子句。这是保证数据正确排序的唯一方法。
    • SELECT order_num, COUNT(*) AS items FROM OrderItems GROUP BY order_num HAVING COUNT(*) >= 3 ORDER BY items, order_num;
  • SELECT 子句顺序
    • 所学过的子句的顺序
      • SELECT 要返回的表达式,必须使用
      • FROM 从中检索数据的表,仅在从表选择数据时使用
      • WHERE 行级过滤,不必须使用
      • GROUP BY 分组说明,仅在按组计算聚集时使用
      • HAVING 组级过滤,不必须使用
      • ORDER BY 输出排序顺序,不必须使用

第十一课 使用子查询

  • 子查询

    • 查询(query)任何SQL语句都是查询。但此术语一般指 SELECT 语句。
    • SELECT 语句 是 SQL 的查询。SQL 还允许创建子查询(subquery),即嵌套在其他查询中的查询。
  • 利用子查询进行过滤

    • 在 SELECT 语句中,子查询总是从内向外处理。
    SELECT cust_id
    FROM Orders
    WHERE order_num IN (SELECT order_num
                      FROM OrderItems
                      WHERE prod_id = 'RGAN01');
    
    • 对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询。
    • 作为子查询的 SELECT 语句只能查询单个列。企图检索多个列将返回错误。
  • 作为计算字段使用子查询

    • 使用子查询的另一方法是创建计算字段。
    SELECT cust_name,
            cust_state,
            (SELECT COUNT(*)
            FROM Orders
            WHERE Orders.cust_id = Customers.cust_id) AS orders
    FROM Customers
    ORDER BY cust_name;
    
    • 虽然子查询在构造这种 SELECT 语句时极有用,但必须注意限制有歧义的列。

第十二课 联结表

  • 联结

    • SQL 最强大的功能之一就是能在数据查询的执行中联结(join)表。联结是利用 SQL 的 SELECT 能执行的最重要的操作。
    • 关系表
      • 关系表的设计就是要把信息分解成多个表,一类数据一个表。各表通过某些共同的值互相关联(所以才叫关系数据库)。
      • 可伸缩(scale)能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称为可伸缩性好(scale well)。
    • 为什么使用联结
      • 联结是一种机制,用来在一条 SELECT 语句中关联表,因此称为联结。使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行。
  • 创建联结

    • 创建联结非常简单,指定要联结的所有表以及关联它们的方式即可。
    SELECT vend_name, prod_name, prod_price
    FROM Vendors, Products
    WHERE Vendors.vend_id = Products.vend_id;
    
    • 在引用的列可能出现歧义时,必须使用完全限定列名(用一个句点分隔表名和列名)。

    • WHERE子句的重要性
      -笛卡儿积(cartesian product)由没有联结条件的表关系返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数

      • 要保证所有联结都有 WHERE 子句,否则 DBMS 将返回比想要的数据多得多的数据。
    • 内联结

      • 目前为止使用的联结称为等值联结(equijoin),它基于两个表之间的相等测试。这种联结也称为内联结(inner join)。
      SELECT vend_name, prod_name, prod_price
      FROM Vendors INNER JOIN Products
      ON Vendors.vend_id = Products.vend_id;
      
      • 传递给 ON 的实际条件与传递给 WHERE 的相同。
    • 联结多个表

      • SQL 不限制一条 SELECT 语句中可以联结的表的数目。创建联结的基本规则也相同。首先列出所有表,然后定义表之间的关系。
      SELECT prod_name, vend_name, prod_price, quantity
      FROM OrderItems, Products, Vendors
      WHERE Products.vend_id = Vendors.vend_id
      AND OrderItems.prod_id = Products.prod_id
      AND order_num = 20007;
      

你可能感兴趣的:(数据库,sql)