数据库系统概念之SQL数据定义、SQL查询语句的基本结构

1. SQL数据定义:

SQL数据的基本类型

char(n):固定长度的字符串,用户指定长度n,也可以使用全称character。 varchar:可变长度的字符串,用户指定最大长度n,等价于全称character varying。 int:整数类型,等价于全称integer。 smallint:小整数类型。 numeric(p,d):定点数,精度由用户指定。这个数有p位数字(加上一位符号位),其中d位数字在小数点右边。所以在这一个类型的字段上,numeric(3,1)可以精确存储44.5。 real,double precision:浮点数与双精度浮点数,精度与机器相关。 float(n):精度至少为n位的浮点数。

每个类型都有可能包含一个被称为空值的特殊值,表示一个缺失的值

我们建议始终用varchar类型而不是char类型(字符串匹配的时候会出错) SQL提供 nvarchar 类型来存放使用 Unicode 表示的多语言数据

基本模式定义

create table 命令后用 ; 结束(与c++类似,语句结束后用;结束) SQL支持许多种不同的完整性约束:

primary key:主码的属性必须非空且唯一,也就是说没有一个元组在主码的属性上取空值(为每个关系指定一个主码会更好)。

foreign key reference:表示关系中任意元组在属性上的取值必须对应于关系S中某元组在主码属性上的取值。

not null:表示该属性上不允许空值。 insert 命令:将数据加载到关系中。

insert into instructor values (10211,’Smith’,’Biology’,6000); 从SQL中去掉一个关系,使用 drop 命令。

drop table r;是比delete table r;更强的语句,后者保留关系 r ,但删除r中的所有元组。前者不仅删除r的所有元组,还删除r的模式。一旦 r 被去掉,必须用 create 命令来创建。 用 alter 命令为已有的关系增加属性。

alter table r add A,D; A 是待添加属性的名字,D 是待添加属性的域。

alter table r drop A;从关系中去掉属性(SQL Sever 2012 不支持)。

2.SQL查询语句的基本结构

单关系查询

强行删除重复的行,可在 select 后加入关键词 distinct 。

select distinct dept_name
from instructor;

SQL允许我们使用关键词all来显式的指明不去除重复。

select all distinct dept_name
from instructor;

select 子句还可以含有 +、-、*、/运算符的运算表达式,运算对象可以是常熟或元组的属性。 where 子句允许只选出那些在 from 子句的结果关系中满足特定谓词的元组。 SQL允许在 where 子句中使用逻辑连词 and 、or、not。

多关系查询

与单关系查询类似

通常来说,一个SQL查询的含义可以理解为:

1. 为 from 子句中列出的关系产生笛卡尔积。

2. 在步骤1的结果上应用where子句中指定的谓词。

3. 对于步骤2结果中的每个元组,输出 select 子句中指定的属性(或表达式的结果)。

自然连接

自然连接运用作用于两个关系,并产生一个关系作为结果。不同于两个关系上的笛卡尔积,它将第一个关系中的每个元组与第二个关系的所有元组都进行连接;自然连接只考虑那些在两个关系模式中都出现的属性上取值相同的元组对。 自然连接可以简洁的写为:(在除了SQL sever 中可以使用

select name,course 
from instructor natural join teachers;

在SQL sever中使用

SELECT name,course_id FROM instructor INNER JOIN teaches ON instructor.ID> = teaches.ID

附加基本运算

以上的查询方法,遇到两个关系中同名的属性,结果中就会出现重复的属性名。所以要进行更名操作。old_name AS new_name

SELECT name AS instructor_name,course_id
FROM instructor,teaches
WHERE instructor.ID = teaches.ID;

重名关系的另一个原因是为了适用于需要比较同一个关系中的元组的情况。为此我们需要把一个关系跟他自身进行笛卡尔积运算,如果不重名的话,就不可能把一个元组与其他元组区分开。

SELECT DISTINCT T.name
FROM instructor AS T,instructor AS S
WHERE T.salary > S.salary AND S.dept_name = 'Biology';

上面的查询中 T与S被看成是instructor的两个拷贝,更准确的说法是被声明为instructor关系的别名。以上用文字表达为:找出满足下面教师条件的所有教师姓名,他们比Biology系教师的最低工资要高。

字符串运算:SQL中使用一对引号来标识字符串,如果单引号是字符串的组成部分,那么用两个单引号字符来表示。it’s right = it”s right
字符串上可以使用LIKE操作符来实现模式匹配。 允许使用NOT LIKE寻找不匹配项。
百分号(%):匹配任意子串。
下划线(_):匹配任意一个字符串。

SELECT dept_name
FROM department
WHERE building LIKE '%Watson%';

ORDER BY 子句可以让查询结果中的元组按排序顺序显示。在上面的例子中,在最后一行加上ORDER BY dept_name DESC表示将插叙结果降序排列,ASC为升序排列。 为了简化WHERE子句,SQL提供between比较运算符来说明一个值是小于或者等于某个值,同时大于或等于另一个值的。类似的也可以使用NOT BETWEEN。

SELECT name
FROM instructor
WHERE salary BETWEEN 90000 AND 100000;

SQL允许我们用记号(v1,v2…..vn)来表示一个分量值分别为v1,v2…..vn的n维元组。(SQL SEVER 2012 中不支持

SELECT name,course_id
FROM instructor,teaches
WHERE (instructor.ID,dept_name) = (teaches.ID,'Biology');

集合运算

SQL作用在关系上的UNION、INTERSECT和EXCEPT运算对应于数学集合论中的∪、∩、-运算。 与SELECT运算不同,UNION运算自动去除重复。如果我们想保留所有重复,就必须用UNION ALL代替UNION。

(SELECT course_id
FROM section
WHERE semester = 'Fall' AND year = 2009)
UNION
(SELECT course_id
FROM section
WHERE semester = 'Spring' AND year = 2010);

INTERSECT运算自动去除重复,如果我们想保留所有重复,就必须用INTERSECT ALL代替INTERSECT。 EXCEPT运算从其第一个输入中输出所有不出现在第二个输入中的元组,也即它执行差集操作。此运算在执行差集操作之前自动去除输入中的重复。如果我们想保留所有重复,就必须用EXCEPT ALL代替EXCEPT。

空值

如果算数表达式的任一输入为空,该算数表达式(+、-、*、/)结果为空。

由于在where子句的谓词中可以对比较结果使用诸如and、or和not的布尔运算,所以这些布尔运算的定义也被扩展到可以处理unknown值。

and:true and unknown 的结果是unknown,false and unknown 的结果是false,unknown and unknown 的结果是unknown。 or:true and unknown 的结果是true,false and unknown 的结果是unknown,unknown and unknown 的结果是unknown。 not:not unknown 的结果是 unknown。

SQL中使用特殊的谓词null测试空值。

SELECT name
FROM instructor
WHERE salary IS NULL;

聚集函数

聚集函数是以值的一个集合(集或多重集)为输入,返回单个值的函数。SQL中提供了5个固有的聚集函数。

平均值:avg 最小值:min 最大值:max 总和:sum 计数:count

SQL不允许用count(*)时使用distinct

SELECT AVG(salary) AS avg_salary
FROM instructor
WHERE dept_name = 'Comp. Sci.';

distinct为去除重复函数。SELECT DISTINCT 列名称 FROM 表名称。 分组聚集:有时我们希望将单个函数作用在单个元组集上,而且也希望作用于一组元组集上,在SQL中可以使用group by子句实现这个愿望。group by 子句中给出一个或者多个属性是用来构造分组的。在group by子句中的所有属性上的取值相同的元组将被分在一个组中。

SELECT dept_name,AVG(salary) AS avg_salary
FROM instructor
GROUP BY dept_name;

having子句:having子句针对group by 子句构成的分组,其中的谓词在形成分组后才起作用。

SELECT dept_name,AVG(salary) AS avg_salary
FROM instructor
GROUP BY dept_name
HAVING AVG(salary) > 42000;
(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐