练掌握SQL是数据库用户的宝贵财 富。在本文中,我们将引导你掌握四条最基本的数据 *** 作语句—SQL的核心功能—来依次介绍比较 *** 作符、选择断言以及三值逻辑。当你完成这些学习后,显然你已经开始算是精通SQL了。
在我们开始之前,先使用CREATE TABLE语句来创建一个表(如图1所示)。DDL语句对数据库对象如表、列和视进行定义。它们并不对表中的行进行处理,这是因为DDL语句并不处理数据库中实际的数据。这些工作由另一类SQL语句—数据 *** 作语言(DML)语句进行处理。
SQL中有四种基本的DML *** 作:INSERT,SELECT,UPDATE和DELETE。由于这是大多数SQL用户经常用到的,我们有必要在此对它们进行一一说明。在图1中我们给出了一个名为EMPLOYEES的表。其中的每一行对应一个特定的雇员记录。请熟悉这张表,我们在后面的例子中将要用到它。
INSERT语句
用户可以用INSERT语句将一行记录插入到指定的一个表中。例如,要将雇员John Smith的记录插入到本例的表中,可以使用如下语句:
INSERT INTO EMPLOYEES VALUES
('Smith','John','1980-06-10',
'Los Angles',16,45000)
通过这样的INSERT语句,系统将试着将这些值填入到相应的列中。这些列按照我们创建表时定义的顺序排列。在本例中,第一个值“Smith”将填到第一个列LAST_NAME中;第二个值“John”将填到第二列FIRST_NAME中……以此类推。
我们说过系统会“试着”将值填入,除了执行规则之外它还要进行类型检查。如果类型不符(如将一个字符串填入到类型为数字的列中),系统将拒绝这一次 *** 作并返回一个错误信息。
如果SQL拒绝了你所填入的一列值,语句中其他各列的值也不会填入。这是因为SQL提供对事务的支持。一次事务将数据库从一种一致性转移到另一种一致性。如果事务的某一部分失败,则整个事务都会失败,系统将会被恢复(或称之为回退)到此事务之前的状态。
回到原来的INSERT的例子,请注意所有的整形十进制数都不需要用单引号引起来,而字符串和日期类型的值都要用单引号来区别。为了增加可读性而在数字间插入逗号将会引起错误。记住,在SQL中逗号是元素的分隔符。
同样要注意输入文字值时要使用单引号。双引号用来封装限界标识符。
对于日期类型,我们必须使用SQL标准日期格式(yyyy-mm-dd),但是在系统中可以进行定义,以接受其他的格式。当然,2000年临近,请你最好还是使用四位来表示年份。
既然你已经理解了INSERT语句是怎样工作的了,让我们转到EMPLOYEES表中的其他部分:
INSERT INTO EMPLOYEES VALUES
('Bunyan','Paul','1970-07-04',
'Boston',12,70000)
INSERT INTO EMPLOYEES VALUES
('John','Adams','1992-01-21',
'Boston',20,100000)
INSERT INTO EMPLOYEES VALUES
('Smith','Pocahontas','1976-04-06',
'Los Angles',12,100000)
INSERT INTO EMPLOYEES VALUES
('Smith','Bessie','1940-05-02',
'Boston',5,200000)
INSERT INTO EMPLOYEES VALUES
('Jones','Davy','1970-10-10',
'Boston',8,45000)
INSERT INTO EMPLOYEES VALUES
('Jones','Indiana','1992-02-01',
'Chicago',NULL,NULL)
在最后一项中,我们不知道Jones先生的工薪级别和年薪,所以我们输入NULL(不要引号)。NULL是SQL中的一种特殊情况,我们以后将进行详细的讨论。现在我们只需认为NULL表示一种未知的值。
有时,像我们刚才所讨论的情况,我们可能希望对某一些而不是全部的列进行赋值。除了对要省略的列输入NULL外,还可以采用另外一种INSERT语句,如下:
INSERT INTO EMPLOYEES(
FIRST_NAME, LAST_NAME,
HIRE_DATE, BRANCH_OFFICE)
VALUE(
'Indiana','Jones',
'1992-02-01','Indianapolis')
这样,我们先在表名之后列出一系列列名。未列出的列中将自动填入缺省值,如果没有设置缺省值则填入NULL。请注意我们改变了列的顺序,而值的顺序要对应新的列的顺序。如果该语句中省略了FIRST_NAME和LAST_NAME项(这两项规定不能为空),SQL *** 作将失败。
让我们来看一看上述INSERT语句的语法图:
INSERT INTO table
[(column )]
VALUES
(columnvalue [])
和前一篇文章中一样,我们用方括号来表示可选项,大括号表示可以重复任意次数的项(不能在实际的SQL语句中使用这些特殊字符)。VALUE子句和可选的列名列表中必须使用圆括号。
SELECT语句
SELECT语句可以从一个或多个表中选取特定的行和列。因为查询和检索数据是数据库管理中最重要的功能,所以SELECT语句在SQL中是工作量最大的部分。实际上,仅仅是访问数据库来分析数据并生成报表的人可以对其他SQL语句一窍不通。
SELECT语句的结果通常是生成另外一个表。在执行过程中系统根据用户的标准从数据库中选出匹配的行和列,并将结果放到临时的表中。在直接SQL(direct SQL)中,它将结果显示在终端的显示屏上,或者将结果送到打印机或文件中。也可以结合其他SQL语句来将结果放到一个已知名称的表中。
SELECT语句功能强大。虽然表面上看来它只用来完成本文第一部分中提到的关系代数运算“选择”(或称“限制”),但实际上它也可以完成其他两种关系运算—“投影”和“连接”,SELECT语句还可以完成聚合计算并对数据进行排序。
SELECT语句最简单的语法如下:
SELECT columns FROM tables
当我们以这种形式执行一条SELECT语句时,系统返回由所选择的列以及用户选择的表中所有指定的行组成的一个结果表。这就是实现关系投影运算的一个形式。
让我们看一下使用图1中EMPLOYEES表的一些例子(这个表是我们以后所有SELECT语句实例都要使用的。而我们在图2和图3中给出了查询的实际结果。我们将在其他的例子中使用这些结果)。
假设你想查看雇员工作部门的列表。那下面就是你所需要编写的SQL查询:
SELECT BRANCH_OFFICE FROM EMPLOYEES
以上SELECT语句的执行将产生如图2中表2所示的结果。
由于我们在SELECT语句中只指定了一个列,所以我们的结果表中也只有一个列。注意结果表中具有重复的行,这是因为有多个雇员在同一部门工作(记住SQL从所选的所有行中将值返回)。要消除结果中的重复行,只要在SELECT语句中加上DISTINCT子句:
SELECT DISTINCT BRANCH_OFFICE
FROM EMPLOYEES
这次查询的结果如表3所示。
现在已经消除了重复的行,但结果并不是按照顺序排列的。如果你希望以字母表顺序将结果列出又该怎么做呢?只要使用ORDER BY子句就可以按照升序或降序来排列结果:
SELECT DISTINCT BRANCH_OFFICE
FROM EMPLOYEES
ORDER BY BRANCH_OFFICE ASC
这一查询的结果如表4所示。请注意在ORDER BY之后是如何放置列名BRANCH _OFFICE的,这就是我们想要对其进行排序的列。为什么即使是结果表中只有一个列时我们也必须指出列名呢?这是因为我们还能够按照表中其他列进行排序,即使它们并不显示出来。列名BRANCH_ OFFICE之后的关键字ASC表示按照升序排列。如果你希望以降序排列,那么可以用关键字DESC。
同样我们应该指出ORDER BY子句只将临时表中的结果进行排序;并不影响原来的表。
假设我们希望得到按部门排序并从工资最高的雇员到工资最低的雇员排列的列表。除了工资括号中的内容,我们还希望看到按照聘用时间从最近聘用的雇员开始列出的列表。以下是你将要用到的语句:
SELECT BRANCH_OFFICE,FIRST_NAME,
LAST_NAME,SALARY,HIRE_DATE
FROM EMPLOYEES
ORDER BY SALARY DESC,
HIRE_DATE DESC
这里我们进行了多列的选择和排序。排序的优先级由语句中的列名顺序所决定。SQL将先对列出的第一个列进行排序。如果在第一个列中出现了重复的行时,这些行将被按照第二列进行排序,如果在第二列中又出现了重复的行时,这些行又将被按照第三列进行排序……如此类推。这次查询的结果如表5所示。
将一个很长的表中的所有列名写出来是一件相当麻烦的事,所以SQL允许在选择表中所有的列时使用*号:
SELECT * FROM EMPLOYEES
这次查询返回整个EMPLOYEES表,如表1所示。
下面我们对开始时给出的SELECT语句的语法进行一下更新(竖直线表示一个可选项,允许在其中选择一项。):
SELECT [DISTINCT]
(column [])| *
FROM table [ ]
[ORDER BY column [ASC] | DESC
[ ]]
定义选择标准
在我们目前所介绍的SELECT语句中,我们对结果表中的列作出了选择但返回的是表中所有的行。让我们看一下如何对SELECT语句进行限制使得它只返回希望得到的行:
SELECT columns FROM tables [WHERE predicates]
WHERE子句对条件进行了设置,只有满足条件的行才被包括到结果表中。这些条件由断言(predicate)进行指定(断言指出了关于某件事情的一种可能的事实)。如果该断言对于某个给定的行成立,该行将被包括到结果表中,否则该行被忽略。在SQL语句中断言通常通过比较来表示。例如,假如你需要查询所有姓为Jones的职员,则可以使用以下SELECT语句:
SELECT * FROM EMPLOYEES
WHERE LAST_NAME = 'Jones'
LAST_NAME = 'Jones'部分就是断言。在执行该语句时,SQL将每一行的LAST_NAME列与“Jones”进行比较。如果某一职员的姓为“Jones”,即断言成立,该职员的信息将被包括到结果表中(见表6)。
使用最多的六种比较
我们上例中的断言包括一种基于“等值”的比较(LAST_NAME = 'Jones'),但是SQL断言还可以包含其他几种类型的比较。其中最常用的为:
等于 =
不等于 <>
小于 <
大于 >
小于或等于 <=
大于或等于 >=
下面给出了不是基于等值比较的一个例子:
SELECT * FROM EMPLOYEES
WHERE SALARY >50000
DECLARE CHOICE2 CURSOR WITH RETURN TO CALLER FOR --声明游标 CHOICE2SELECT COMPANYID,DEPTID,SEQID,SUBMITTIME,SUBMITDATE,
B.GRADEDESC HYEAR,PRODUCTID,PRODUCTCODE,PRODUCTDESC,
A.GRADEID,PRICE,SFZDPY,LQUANT,MQUANT,MCQUANT,LCQUANT,
UQUANT,OTHQUANT1,OTHQUANT2,OTHQUANT3,OTHQUANT4,EMP1,EMP2,STATUS,A.REMARK,
DECIMAL(ABS(MCQUANT-MQUANT)/NULLIF(MQUANT,0)*100,10,2)TAG
FROM T_SUPPLY_PPB_HY A
LEFT JOIN T_SUPPLY_GRADATION B ON A.GRADEID=B.GRADEID
WHERE HYEAR=TO_CHAR(P_NF)||P_BN
ORDER BY B.GRADEID,PRODUCTCODE,A.PRICE
--1.DECIMAL(P,S)十进制数,小数点位置由数字的精度(P)和小数位(S)确定。
-- 精度是数字的总位数,必须小于32。小数位是小数部分数字的位数且总是小于或等于精度值。
-- 如果未指定精度和小数位,则十进制值的缺省精度为5,缺省小数位为0。
--2.语法:NULLIF ( expression , expression )
-- expression:(常量、列名、函数、子查询或算术运算符、按位运算符以及字符串运算符的任意组)
-- 如果两个表达式不相等,NULLIF 返回第一个 expression 的值。如果相等,NULLIF 返回第一个 expression 类型的空值。如果两个表达式相等且结果表达式为 NULL,NULLIF 等价于 CASE 的搜索函数。
DB 提供了关连式资料库的查询语言 SQL (Structured Query Language) 是一种非常口语化 既易学又易懂的语法 此一语言几乎是每个资料库系统都必须提供的 用以表示关连式的 *** 作 包含了资料的定义(DDL)以及资料的处理(DML) SQL原来拼成SEQUEL 这语言的原型以 系统 R 的名字在 IBM 圣荷西实验室完成 经过IBM内部及其他的许多使用性及效率测试 其结果相当令人满意 并决定在系统R 的技术基础发展出来 IBM 的产品 而且美国国家标准学会(ANSI)及国际标准化组织(ISO)在 遵循一个几乎是以 IBM SQL 为基础的标准关连式资料语言定义 一 资料定义 DDL(Data Definition Language) 资料定语言是指对资料的格式和形态下定义的语言 他是每个资料库要建立时候时首先要面对的 举凡资料分哪些表格关系 表格内的有什么栏位主键 表格和表格之间互相参考的关系等等 都是在开始的时候所必须规划好的 1 建表格 CREATE TABLE table_name( column DATATYPE [NOT NULL] [NOT NULL PRIMARY KEY] column DATATYPE [NOT NULL] )说明 DATATYPE 是资料的格式 详见表 NUT NULL 可不可以允许资料有空的(尚未有资料填入) PRIMARY KEY 是本表的主键 2 更改表格 ALTER TABLE table_name ADD COLUMN column_name DATATYPE 说明 增加一个栏位(没有删除某个栏位的语法 ALTER TABLE table_nameADD PRIMARY KEY (column_name)说明 更改表得的定义把某个栏位设为主键 ALTER TABLE table_nameDROP PRIMARY KEY (column_name)说明 把主键的定义删除 3 建立索引 CREATE INDEX index_name ON table_name (column_name)说明 对某个表格的栏位建立索引以增加查询时的速度 4 删除 DROP table_nameDROP index_name 二 的资料形态 DATATYPEs *** allint 位元的整数 interger 位元的整数 decimal(p s)p 精确值和 s 大小的十进位整数 精确值p是指全部有几个数(digits)大小值 s是指小数点后有几位数 如果没有特别指定 则系统会设为 p= s= float 位元的实数 double 位元的实数 char(n)n 长度的字串 n不能超过 varchar(n)长度不固定且其最大长度为 n 的字串 n不能超过 graphic(n)和 char(n) 一样 不过其单位是两个字元 double bytes n不能超过 这个形态是为了支援两个字元长度的字体 例如中文字 vargraphic(n)可变长度且其最大长度为 n 的双字元字串 n不能超过 date包含了 年份 月份 日期 time包含了 小时 分钟 秒 timestamp包含了 年 月 日 时 分 秒 千分之一秒 三 资料 *** 作 DML (Data Manipulation Language) 资料定义好之后接下来的就是资料的 *** 作 资料的 *** 作不外乎增加资料(insert) 查询资料(query) 更改资料(update) 删除资料(delete)四种模式 以下分 别介绍他们的语法 1 增加资料 INSERT INTO table_name (column column )VALUES ( value value )说明 若没有指定column 系统则会按表格内的栏位顺序填入资料 栏位的资料形态和所填入的资料必须吻合 table_name 也可以是景观 view_name INSERT INTO table_name (column column )SELECT columnx columny FROM another_table说明 也可以经过一个子查询(subquery)把别的表格的资料填入 2 查询资料 基本查询SELECT column columns FROM table_name说明 把table_name 的特定栏位资料全部列出来 SELECT *FROM table_name WHERE column = xxx [AND column >yyy] [OR column <>zzz] 说明 * 表示全部的栏位都列出来 WHERE 之后是接条件式 把符合条件的资料列出来 SELECT column column FROM table_name ORDER BY column [DESC]说明 ORDER BY 是指定以某个栏位做排序 [DESC]是指从大到小排列 若没有指明 则是从小到大 排列组合查询 组合查询是指所查询得资料来源并不只有单一的表格 而是联合一个以上的表格才能够得到结果的 SELECT * FROM table table WHERE lum =lumn 说明 查询两个表格中其中 column 值相同的资料 当然两个表格相互比较的栏位 其资料形态必须相同 一个复杂的查询其动用到的表格可能会很多个 整合性的查询 SELECT COUNT (*)FROM table_nameWHERE column_name = xxx说明 查询符合条件的资料共有几笔 SELECT SUM(column )FROM table_name说明 计算出总和 所选的栏位必须是可数的数字形态 除此以外还有 AVG() 是计算平均 MAX() MIN()计算最大最小值的整合性查询 SELECT column AVG(column )FROM table_nameGROUP BY column HAVING AVG(column ) >xxx说明 GROUP BY: 以column 为一组计算 column 的平均值必须和 AVG SUM等整合性查询的关键字一起使用 HAVING : 必须和 GROUP BY 一起使用作为整合性的限制 复合性的查询SELECT *FROM table_name WHERE EXISTS (SELECT *FROM table_name WHERE conditions )说明 WHERE 的 conditions 可以是另外一个的 query EXISTS 在此是指存在与否 SELECT *FROM table_name WHERE column IN (SELECT column FROM table_name WHERE conditions )说明 IN 后面接的是一个集合 表示column 存在集合里面 SELECT 出来的资料形态必须符合 column 其他查询SELECT *FROM table_name WHERE column LIKE x% 说明 LIKE 必须和后面的 x% 相呼应表示以 x为开头的字串 SELECT *FROM table_name WHERE column IN ( xxx yyy )说明 IN 后面接的是一个集合 表示column 存在集合里面 SELECT *FROM table_name WHERE column BEEEN xx AND yy说明 BEEEN 表示 column 的值介于 xx 和 yy 之间 3 更改资料 UPDATE table_nameSET column = xxx WHERE conditoins说明 更改某个栏位设定其值为 xxx nditions 是所要符合的条件 若没有 WHERE 则整个 table 的那个栏位都会全部被更改 4 删除资料 DELETE FROM table_nameWHERE conditions说明 删除符合条件的资料 说明 关于WHERE条件后面如果包含有日期的比较 不同数据库有不同的表达式 具体如下 ( )如果是ACCESS数据库 则为 WHERE mydate># # ( )如果是ORACLE数据库 则为 WHERE mydate>cast( as date) 或 WHERE mydate>to_date( yyyy mm dd )在Delphi中写成 thedate= query SQL add( select * from abc where mydate>cast( + +thedate+ + as date) )如果比较日期时间型 则为 WHERE mydatetime>to_date( : : yyyy mm dd hh :mi:ss ) lishixinzhi/Article/program/SQLServer/201311/21970
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)