SQL必知必会笔记二

创建计算字段

计算字段

  • 字段 : 基本上与 的意思相同
  • 计算字段是运行时在 SELECT 语句内创建的

拼接字段

  • 拼接 : 将值连接到一起. 将一个值附加到另一个值构成一个单值.

  • 操作符:

    • + 加号
    • ||
    select vend_name || '(' || vend_country || ')'
    from Vendors;
  • 函数 PTRIM() : 去除值右边的所有的空格

    select  RTRIM(vend_name ) || '(' || vend_country || ')'
    from Vendors;

执行算术计算

select prod_id ,quantity,item_price
from OrderItems
where order_num = 20008;
-- 用字段进行算术计算
select prod_id,quantity,item_price,
quantity*item_price as expanded_price
from OrderItems
where order_num = 20008;

使用函数处理数据

函数

  • 大多数SQL实现支持以下类型的函数
    • 处理文本字符串的文本函数
    • 数值数据算数计算的数值函数
    • 日期与时间函数
    • 特殊系统函数

文本处理函数

  • UPPER 函数 : 将文本转成大写

  • select vend_name,UPPER(vend_name) as vend_name_upcase
    from Vendors
    order by vend_name;
  • 常用文本处理函数:

函数 说明
LEFT 返回字符串左边的字符
LENGTH 返回字符串长度
LOWER 转成小写
RIGHT 返回字符串右边的字符
LTRIM 去除字符串左边的空格
RTRIM 去除字符串右边的空格
UPPER 转成大写
SOUNDEX 返回字符串的soundex值

- SOUNDEX 不一定支持

日期与时间处理函数

数组处理函数

函数 说明
ABS 绝对值
COS 余弦
EXP 指数
PI π
SIN 正弦
SQRT 平方根
TAN 正切

汇总数据

聚集函数

函数 说明
AVG 返回某个列的平均值
COUNT 返回某个列的行数
MAX 返回某列的最大值
MIN 返回某列的最小值
SUM 返回某列的值之和
select AVG(prod_price) as avg_price
from Products;

组合聚类函数

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 BYHAVING 子句
  • 分组可以将数据分成多个逻辑组. 对每个组进行聚类计算.

创建分组

  • 分组的使用 SELECT 子句 GROUP BY 创建

    select vend_id,count(*) as num_prods
    from Products
    group by vend_id;

过滤分组

  • WHERE 过滤的是指定行而不是分组

  • HAVING 子句 : 用于过滤分组

  • HAVING 支持所有 WHERE 操作符

    select cust_id ,count(*) as orders
    from Orders
    group by cust_id
    having count(*)>=2;
  • HAVINGWHERE 的差别

    • WHERE 在数据分组前进行过滤

    WHERE 排除的行不包括在分组中,这可能会改变计算值.从而影响 HAVING 分组过滤

    • HAVING 数据分组后进行过滤
    select vend_id,count(*) as num_prods
    from Products
    where prod_price >=4
    group by vend_id
    having count(*) >=2;
    
    select vend_id,count(*) as num_prods
    from Products
    -- where prod_price >=4
    group by vend_id
    having count(*) >=2;

分组与排序

  • ORDER BY VS GROUP BY
order BY GROUP BY
对产生的输出排序 对行分组 但输出可能不是分组的顺序
任意列都可以使用 只能使用选择列 or 表示式列
不一定需要 若何聚类函数一起使用,则必须使用
  SELECT order_num, COUNT(*) AS items
  FROM OrderItems
  GROUP BY order_num
  HAVING COUNT(*) >= 3
  ORDER BY items, order_num;

SELECT 子句顺序

子句 说明 是否必须使用
SELECT 要返回的列or表达式
FROM 从中检索数据的表 仅从表中选择数据时使用
WHERE 行级过滤
GROUP BY 分组说明 仅在按组计算聚类时使用
HAVING 组级过滤
ORDER BY 输出排序顺序

使用子查询

利用子查询进行过滤

  • 子查询总是从内向外处理
SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
                    FROM OrderItems
                    WHERE prod_id = 'RGAN01');

作为计算字段使用子查询

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 语句就索引出数据!

创建联结

select vend_name,prod_name,prod_price
from Vendors,Products
where Vendors.vend_id=Products.vend_id;
  • 与之前 SELECT 语句的最大差别在于第三句话.
  • WHERE 子句的重要性: WHERE 子句作为过滤条件,只包含那些匹配给定条件(这里是联结条件)的行
  • 由没有 联结条件 的表关系返回的结果为 笛卡尔积. 检索出的行数为表一行数乘以表二行数.

内联结

  • 内联结(inner join) : 等值联结 基于两个表之间的相等测试.

    两个表之间的关系是以 INNER JOIN 指定的部分FROM子句

    联结条件用 ON 子句

    SELECT vend_name, prod_name, prod_price
    FROM Vendors INNER JOIN Products
    ON Vendors.vend_id = Products.vend_id;

联结多个表

  • 创建联结的基本规则相同。首先列出所有表,然后定义表之间的关系
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; -- 过滤
  • 子查询 与 联结

    -- 子查询
    SELECT cust_name, cust_contact
    FROM Customers
    WHERE cust_id IN (SELECT cust_id
    FROM Orders
    WHERE order_num IN (SELECT order_num
    FROM OrderItems
    WHERE prod_id = 'RGAN01'))
    
    -- 联结多个表
    select cust_name,cust_contact
    from Customers,Orders,OrderItems
    where Customers.cust_id = Orders.cust_id
    and Orders.order_num = OrderItems.order_num
    and prod_id = 'RGAN01'
    
    

创建高级联接

使用表别名

  • 使用别名引用被检索的表列. 给列起别名的语法如下:

    select RTRIM(vend_name)+'('+RTRIM(vend_country)+')'
    as vend_tile
    from Vendors
    order by vend_name

  • SQL除了可以对列名和计算字段使用别名. 还允许给表明起别名.

    • 缩短SQL语句
    • 允许在一条 SELECT 语句中多次使用相同的表
    select cust_name,cust_contact 
    from Customers as C, Orders as O,OrderItems as OI
    where C.cust_id = O.cust_id
    and O.order_num = OI.order_num
    and prod_id = 'RGAN01'
  • 使用表别名的一个主要原因是能在一条SELECT语句中不止一次引用相同的表

使用不同类型的联结

  • 内联结 : 等值联结

  • 自联结(self-join) :

    -- 子查询
    select cust_id,cust_name,cust_contact
    from Customers
    where cust_name = (select cust_name 
    from Customers
    where cust_contact = 'Jim Jones');
    
    -- 自联结
    -- Customers第一次出现用了别名C1,第二次出现用了别名C2
    select c1.cust_id,c1.cust_name,c1.cust_contact
    from Customers as c1,Customers as c2
    where c1.cust_name = c2.cust_name
    and c2.cust_contact='Jim Jones';
  • 自然联结(natural join) :

    • 标准的联结(eg.内联结)返回所有数据,相同的
      列甚至多次出现.

    • 自然联结排除多次出现,使每一列只返回一次.

    • 自然联结要求只能选择那些唯一的列.

    • 一般通过对一个表使用通配符(SELECT *).而对其他表的列使用明确的子集来完成.

    • 通配符只对第一个表使用.所有其他列明确列出,所以没有重复的列被检索出来 .

    select c.*,o.order_num,o.order_date,oi.prod_id,oi.quantity,oi.item_price
    from Customers as c,Orders as o, OrderItems as oi
    where c.cust_id = o.cust_id
    and oi.order_num = o.order_num
    and prod_id = 'RGAN01';
  • 外联结(outer join) :

    • 许多联结将一个表中的行与另一个表中的行相关联,但有时候需要包含没有关联行的那些行 .

    • 外联结 : 联结包含了那些在相关表中没有关联行的行

    -- 内联结 它检索所有顾客及其订单
    select Customers.cust_id , Orders.order_num
    from Customers inner join Orders 
    on Customers.cust_id = Orders.cust_id;
    
    -- 外联结 要检索包括没有订单顾客在内的所有顾客
    select Customers.cust_id , Orders.order_num
    from Customers left outer join Orders
    on Customers.cust_id = Orders.cust_id;

使用带聚集函数的联结

-- 检索出所有顾客以及每个顾客所下的订单数
select Customers.cust_id,count(Orders.order_num) as num_ord
from Customers inner join Orders
on Customers.cust_id = Orders.cust_id
group by Customers.cust_id;

-- 外联结时
select Customers.cust_id,count(Orders.order_num) as num_ord
from Customers left outer join Orders
on Customers.cust_id = Orders.cust_id
group by Customers.cust_id

组合查询

如何利用 UNION 操作将多条 SELECT 语句合成一个结果集

  • 多数的SQL查询只包换从一个或多个表中返回数据的单条 SELECT 语句.
  • 多条 SELECT 语句,并将结果作为一个查询结果集返回.这种组合查询通常称为 并(union)或复合查询(compound query)

创建组合查询

  • 使用 UNION

    select cust_name,cust_contact,cust_email
    from Customers
    where cust_state in ('IL','IN','MI')
    union -- UNION指示DBMS执行这两条SELECT语句,并把输出组合成一个查询结果集
    select cust_name,cust_contact,cust_email
    from Customers
    where cust_name = 'Fun4All';
    
    -- 多个WHERE:
    select cust_name,cust_contact,cust_email
    from Customers
    where cust_state in ('IL','IN','MI')
    or cust_name = 'Fun4All';

猜你喜欢

转载自blog.csdn.net/qjh5606/article/details/80217621