SQL必知必会

SQL必知必会

2.检索数据

2.5检索不同的值

distinct指示数据库只返回不同的值,必须直接放在列名的前面。需要注意的是,不能部分使用distinct,其作用于所有的列,不仅仅是跟在其后的那一列。例如,select distinct vend_id, prod_price,除非指定的两列完全相同,否则所有的列都会被检索出来。

2.6限制结果

如果只想返回第一行或者一定数量的行,需要执行特定的操作,然而遗憾的是,不同的数据库相关的实现都有所不同:

  • 如果使用oracle,需要基于rownum(行计数器)来计算行:
select prod_name
from Products
where ROWNUM <=5;
  • 如果使用mysql,需要使用limit子句:
-- 返回不超过5行的数据
select prod_name
from Products
limit 5;

为了得到后面的5行数据,需要指定从哪儿开始以及检索的行数:

select prod_name
from Products
limit 5 offset 5;

第一个数字是指从哪儿开始,第二个数字是检索的行数。需要注意的是,第一个被检索的行是第0行,而不是第1行,因此,limit 1 offset 1会检索第2行,而不是第1行。
另一方面,mysql支持简化版的limit 4 offset 3语句,即limit 3, 4。使用这个语法,逗号之前的值对应offset,逗号之后的值对应limit

3.排序检索数据

3.1排序数据

在指定一条order by子句时,应该保证它是select语句中最后一条子句。如果不是,则会出现错误消息。

5.高级数据过滤

5.3NOT操作符

where子句中的not操作符有且只有一个功能,那就是否定其后所跟的任何条件。总是与其他操作符一起使用,可以用在要过滤的列前,而不仅是在其后。

select prod_name
from products
where not vend_id = 'DLL01'	-- 也可以使用!=操作符来完成
order by prod_name;

在更复杂的子句中,not是非常有用的。例如,在与in操作符联合使用时,not可以非常简单地找出与条件列表不匹配的行。

9.汇总数据

9.1聚集函数

在这里插入图片描述

9.2聚集不同值

聚集函数可以如下使用:

  • 对所有行执行计算,指定ALL参数或不指定参数(因为ALL是默认行为)。
  • 只包含不同的值,指定DISTINCT参数。
select avg(distinct prod_price) as avg_price
from products
where vend_id = 'DLL01';

需要注意的是,使用DISTINCT必须使用列名,不能用于计算或表达式,因此不能用于COUNT(*)
虽然DISTINCT从技术上可用于MIN()MAX(),但这样做实际上没有价值。一个列中的最小值和最大值不管是否只考虑不同值,结果都是相同的。

10.分组数据

10.1数据分组

使用分组可以将数据分为多个逻辑组,对每个组进行聚集计算。

10.2创建分组

GROUP BY子句指示,DBMS分组数据,然后对每个组而不是整个结果集进行聚集。
在使用GROUP BY子句前,需要知道一些重要的规定:

  • GROUP BY子句可以包含任意数目的列,因而可以对分组进行嵌套,更细致地进行数据分组。
  • 在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。
  • GROUP BY子句中列出的每一列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式,不能使用别名
  • 大多数SQL实现不允许GROUP BY列带有长度可变的数据类型(如文本或备注型字段)。
  • 除聚集计算语句外,SELECT语句中的每一列都必须在GROUP BY子句中给出。
  • 如果分组列中包含具有NULL值的行,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
  • GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。
10.3过滤分组

WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。

10.5SELECT子句顺序

在这里插入图片描述

11.使用子查询

11.2利用子查询进行过滤

SELECT语句中,子查询总是从内向外处理。

11.3作为计算字段使用子查询
select cust_name,
       cust_state,
       (select COUNT(*)
       from orders
       where orders.cust_id = customers.cust_id) as orders	-- 完全限定列名
from customers
order by cust_name

子查询对检索出来的每条数据都执行一次。例如,检索出5条数据,子查询会执行5次。

12.联结表

12.1联结
12.1.1关系表

相同的数据出现多次绝不是一件好事,这是关系数据库设计的基础。关系表的设计就是要把信息分解成多个表,一类数据一个表。各表通过某些共同的值互相关联(所以才叫关系数据库)。

12.2创建联结
12.2.1WHERE子句的重要性

由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。

14.组合查询

14.2创建组合查询
14.2.4对组合查询结果排序

在用UNION组合查询时,只能使用一条ORDER BY子句,它必须位于最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况。

15.插入数据

15.2从一个表复制到另一个表

要将一个表的内容复制到一个全新的表(运行中创建的表),可以使用SELECT INTO语句(mysql不支持)。

-- 创建一个名为custcopy的新表,并把customers表的整个内容复制到新表中
select *
into custcopy
from customers;

MySQL中的语法:

create table custcopy as
select * from customers;

在使用SELECT INTO时,需要知道一些事情:

  • 任何SELECT选项和子句都可以使用,包括WHEREGROUP BY
  • 可利用联结从多个表插入数据。
  • 不管从多少个表中检索数据,数据都只能插入到一个表中。

22.高级SQL特性

22.1约束
22.1.2外键

外键是表中的一列,其值必须列在另一个表的主键中。外键是保证引用完整性的极其重要部分。

22.1.3唯一约束

唯一约束用来保证一列(或一组列)中的数据是唯一的。它们类似于主键,但存在以下重要区别:

  • 表可以包含多个唯一约束,但每个表只允许一个主键。
  • 唯一约束列可以包含NULL值。
  • 唯一约束列可以修改或更新。
  • 唯一约束列的值可以重复使用。
  • 与主键不一样,唯一约束不能用来定义外键。
22.1.4检查约束

检查约束用来保证一列(或一组列)中的数据满足一组指定的条件。检查约束的常见用途有以下几点:

  • 检查最小或最大值。例如,防止 0个物品的订单(即使0是合法的数)。
  • 指定范围。例如,保证发货日期大于等于今天的日期,但不超过今天起一年后的日期。
  • 只允许特定的值。例如,在性别字段中只允许M或F。
22.2索引

索引用来排序数据以加快搜索和排序操作的速度。可以在一个或多个列上定义索引,使DBMS保存其内容的一个排过序的列表。在定义了索引后,DBMS搜索排过序的索引,找出匹配的位置,然后检索这些行。
在开始创建索引前,应该记住以下内容:

  • 索引改善检索操作的性能,但降低了数据插入、修改和删除的性能。在执行这些操作时,DBMS必须动态地更新索引。
  • 索引数据可能要占用大量的存储空间。
  • 并非所有数据都适合做索引。取值不多的数据不如具有更多可能值的数据,能通过索引得到那么多的好处。
  • 索引用于数据过滤和数据排序。如果经常以某种特定的顺序排序数据,则该数据可能适合做索引。
  • 可以在索引中定义多个列。这样的索引仅在多个列的顺序排序时有用。如果想按单列排序,则这种索引没有用处。
22.3触发器

触发器是特殊的存储过程,它在特定的数据库活动发生时自动执行。触发器可以与特定表上的INSERTUPDATEDELETE操作(或组合)相关联。
与存储过程不一样(存储过程只是简单的存储SQL语句),触发器与单个的表相关联。触发器内的代码具有以下数据的访问权:

  • INSERT操作中的所有新数据。
  • UPDATE操作中的所有新数据和旧数据。
  • DELETE操作中删除的数据。

下面是触发器的一些常见用途:

  • 保证数据一致。例如,将列都转换为大写。
  • 基于某个表的变动在其他表上执行活动。例如,每当更新或删除一行时将跟踪记录写入某个日志表。
  • 进行额外的验证并根据需要回退数据。例如,保证某个顾客的可用资金不超限定,如果已经超出,则阻塞插入。
  • 计算计算列的值或更新时间戳。
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值