Ⅰ sql语句怎样查询一个范围
SQL方法完成数值区间查询
要求:根据奖金等级表的数值区间,返回奖金对应的等级。
1、链接外部数据:数据--现有链接--浏览更多,在路径中选择数据Excel文件和目标工作表,建立数据链接。
详细步骤参考前面所发的SQL相关文章。
2、编写sql语句。
2.1、使用switch函数,SQL语句为:
select 姓名,奖金,switch(奖金<200,"D级",奖金<300,"C级",奖金<500,"B级",奖金>=500,"A级") as 奖金等级 from [奖金$a1:b11]
switch函数直接判断数值,若数值小于200,返回D级;数值小于300返回C级;数值小于500,返回B级;余下的数值条件要变化为>=500返回A级而不是<=700。
2.2、使用iif函数,SQL语句为:
select 姓名,奖金,iif(奖金<200,"D级",iif(奖金<300,"C级",iif(奖金<500,"B级","A级"))) as 奖金等级 from [奖金$a1:b11]
其基本思路和switch函数相同,类似工作表函数if的嵌套。
2.3、使用betweent...and,SQ语句为:
select a.姓名,a.奖金,b.等级 from [奖金$a1:b11] a,[奖金等级$] b where a.奖金 between b.最小值 and b.最大值
以戴苏明同学为例子,在SQL代码运行的时候,将戴苏明同学的奖金一一和奖金等级表中的数值进行对比,符合区间的就返回区间等级。其他同学亦然。
但是,当奖金超出最大值700的时候就会取不到该条数据。
如刘平的奖金701并不在betweent...and的区间内,返回的结果中没有刘平的数据。
2.4、使用Where比较大小,sql语句为:
select a.姓名,a.奖金,b.等级 from [奖金$a1:b11] a,[奖金等级$] b where a.奖金 >=b.最小值 and a.奖金<=b.最大值
此方法原理和betweent...and一样,当奖金超过最大值700时,数据将有遗漏(刘平)。
当奖金的最大值为700的时候,以上四种方法都得出同样的结果。
当奖金最大值超过700的时候,3、4两个方法将遗漏奖金大于700的数据。
因此,可在设计奖金等级表的时候,可以将最大值700改为一个比较大的数值,使奖金再高也不会超过,则四种方位皆可。
如更改奖金等级表的最大值700为70000,这么大的一个范围,则四种方法都适用。
Ⅱ SQL语句怎样查询一个范围
SQL语句通过“BETWEEN…AND…”语法来查询一个范围。
WHERE子句设置查询条件,过滤掉不需要的数据行。其范围运算符“BETWEEN…AND…”表示表达式值是否在指定的范围内,类似的“NOT BETWEEN…AND…”表示表达式值是否不在指定的范围内。
例如:SELECT * FROM user WHERE age BETWEEN 10 AND 30,用于查询出user表中age值介于10~30间的数据记录。
(2)SQL减去一个范围扩展阅读:
SQL中WHERE子句其它运算符:
1、比较运算符
>、>=、=、<、<=、<>
2、列表运算符
IN (项1,项2……)
NOT IN (项1,项2……)
3、模式匹配符
LIKE、NOT LIKE
4、空值判断符
IS NULL、IS NOT NULL
5、逻辑运算符
NOT、AND、OR
Ⅲ sql语句如何删除一段时间内的记录
删除一段时间内的记录,关键在于删除时筛选条件确定删除范围,数据表中最好是有一个表示时间的字段,根据该时间字段进行时间段的条件判断,进而执行删除
1、使用BETWEEN关键字根据时间字段删除一定时间内的记录
DELETEFROM表名WHERE时间字段BETWEEN开始时间AND结束时间
示例:
'2017-01-0100:00:00'AND'2017-02-0100:00:00'
--删除tb表中2017年1月1日到2017年2月1日的数据
2、使用时间字段比较大小来确定删除范围
--语法:
DELETEFROM表名WHERE时间字段>=开始时间AND时间字段<=结束时间
示例:
DELETEFROMtbWHERECreateTime>='2017-01-0100:00:00'ANDCreateTime<='2017-02-0100:00:00'
Ⅳ sql修改字段值的范围
1、字段的修改
增加字段
ALTER TABLE <表名> ADD <新字段名><数据类型>[约束条件]
对语法格式的说明如下:
1.<表名> 为数据表的名字;
2.<新字段名> 为所要添加的字段的名字;
3.<数据类型> 为所要添加的字段能存储数据的数据类型;
4.[约束条件] 是可选的,用来对添加的字段进行约束。
SQL 默认在表的最后位置添加新字段,如果希望在开头位置(第一列的前面)添加新字段,那么可以使用 FIRST 关键字,语法格式如下:
ALTER TABLE <表名> ADD <新字段名> <数据类型> [约束条件] FIRST;
-- 给actor表首位添加create_date字段
ALTER TABLE actor ADD COLUMN create_date datetime not null DEFAULT '2020-10-01 00:00:00' FIRST;
复制
删除字段
ALTER TABLE <表名> DROP COLUMN <字段名>
-- 将actor_new表的actor_id字段删除
alter table actor_new drop column actor_id;
复制
修改字段
1.修改字段名
ALTER TABLE <表名> RENAME COLUMN A to B
-- 将actor_new表的first_name字段名修改为first_name_new
alter table actor_new rename column first_name to first_name_new;
复制
2.修改字段类型
ALTER TABLE <表名> MODIFY COLUMN <字段名> <类型>
-- 将last_name字段数据类型由varchar(45)修改为char(45)
alter table actor_new modify column last_name char(45) not null;
复制
3.修改字段默认值
ALTER TABLE <表名> ALTER COLUMN <字段名> SET DEFAULT <默认值>
若字段有默认值,则需要先删除字段的约束,在添加新的默认值
根据约束名称删除约束
alter table <表名> alter column <字段名> drop default
-- 若本身存在默认值,则先删除
alter table actor_new alter column last_name drop default;
-- 给last_name添加默认值'洛'
alter table actor_new alter column last_name set default '洛';
复制
4.修改字段位置
将字段的位置修改为数据表的开头位置,使用FIRST关键字将当前字段修改为数据表的第一个字段
ALTER TABLE <表名> MODIFY <字段名> <数据类型> FIRST
-- 将字段first_name调整到actor表的首位
ALTER TABLE actor modify first_name varchar(45) FIRST;
复制
将选中字段修改到某字段之后
ALTER TABLE <表名> MODIFY <字段1名称> <字段1数据类型> AFTER <字段2名称>
-- 将字段first_name调整到last_name之后
ALTER TABLE actor MODIFY first_name varchar(45) AFTER last_name;
复制
2、数据的修改
增加数据
添加数据在SQL篇-创建数据表中有粗略的介绍,这里进行详细说明
1.插入一条新的数据 INSERT INTO <表名>[(列1,列2,列3,…)]VALUES(值1,值2,值3,…)
-- 插入数据的sql语句
insert into tablename(col1,col2,col3) values (value1,value2,value3);
复制
2.通过子查询插入数据 INSERT INTO <表名>[(列1,列2,列3,…)]子查询
-- 把actor_id=10的用户复制一遍
insert into tablename SELECT * FROM actor WHERE actor_id=10;
复制
删除数据
DELETE FROM <表名> [WHERE 删除条件]
注意:不写删除条件表示删除全部!
-- 删除演员编号是6的演员信息
delete from actor WHERE actor_id=6;
复制
更新数据
1.指定要更新数据的内容
UPDATE <表名> SET [字段=值,字段=值…][WHERE 更新条件]
-- 将SMITH(雇员编号为7)的工资修改为3000元,并且每个月有500元的奖金
update myemp set sal=3000,comm=500 where empno=7;
2.基于子查询的更新
UPDATE <表名> SET (列1,列2,…)=(SELECT 列1,列2,…FROM <表名>) [WHERE 查询条件]
-- 将雇员7369的职位、基本工资、雇佣日期更新为与7839相同的信息
update myemp set (job,sal,hiredate) = (select job,sal,hiredate from myemp where empno=7839) where empno=7369;
3.更新替换
-- 将address字段里的 “东” 替换为 “西” ,如下
update test_tb set address=replace(address,'东','西') where id=2
4.插入替换
-- 将id=6的name字段值改为wokou
replace into test_tb VALUES(6,'wokou','新九州岛','日本')
注意:插入替换时,若进行部分替换,则表其余字段要有默认值,否则,要列出该列的所有值
总结:向表中“替换插入”一条数据,如果原表中没有id=6这条数据就作为新数据插入(相当于insert into作用),
如果原表中有id=6这条数据就做替换(相当于update作用),对于没有指定的字段以默认值插入。
Ⅳ SQL如何把表中一个范围的数据提取处理
create table aaa (num1 int,num2 int);
insert into aaa values (1,3);
insert into aaa values (6,9);
--竖版
create function dbo.func_d (@a int)
RETURNS @table table(id int) as
begin
declare @num1 int,@num2 int;
declare mycursor cursor for
select * from aaa;
open mycursor
fetch mycursor into @num1,@num2;
while @@fetch_status=0
begin
while @num1<=@num2
begin
insert into @table values (@num1);
set @num1=@num1+1;
end;
fetch mycursor into @num1,@num2;
end;
return;
end
select * from dbo.func_d(1)
--结果:
id
1
2
3
6
7
8
9
----------------------------------
--横版
create function dbo.func_d2 (@a int)
RETURNS @table table(string varchar(4000)) as
begin
declare @num1 int,@num2 int;
insert into @table values ('a');
declare mycursor cursor for
select * from aaa;
open mycursor
fetch mycursor into @num1,@num2;
while @@fetch_status=0
begin
while @num1<=@num2
begin
update @table set string=string+','+convert(varchar,@num1);
set @num1=@num1+1;
end;
fetch mycursor into @num1,@num2;
end;
update @table set string=stuff(string,1,2,N'');
return;
end
select * from dbo.func_d2(1)
--结果:
string
1,2,3,6,7,8,9
Ⅵ 数据库如何删除表中的一段区间内的所有数据
1 付键 也就是FK formary key
程序交流中心,这是专门为新手学习设立的论坛
二、SQL
Structur query language
结构化查询语言,是操作关系型数据库中的对象。
DDL(Data definition language 数据定义语言),用于建表或删表操作,以及对表约束进行修改
create table , alter table , drop table 对表结构的增删操作。
DML(Data manipulation language 数据操作语言),向表中插入纪录,修改纪录
insert , update , delete , merge
transaction ,事务控制语言,由DML语句组成的,commit; ,rollback;
select 查询语句
dcl 授权语句 grant
三、Oracle
DBMS 数据库管理系统
有Oracle提供,还提供AS,应用服务器
DBA 数据库管理员
四、相关操作
1、sqlplus 访问数据库命令(本地访问/远程访问),和数据库建立连接的命令,是数据库操作的环境
sqlplus 用户名/密码
2、show user 显示当前用户的用户名
改变身份可以直接connect 用户名/密码 --- 这个是sqlplus命令
在sqlplus中可以使用 ! 可以在shell和sqlplus间切换,!shell命令 可以在sqlplus中使用shell命令。
实际上是sqlplus开了子进程来执行shell命令。
3、Oracle数据库中的表分两类:用户表(用户使用操作的表),系统表(数据库系统维护的表,也叫数据字典)
对用户表的DDL操作出发了对系统表的DML操作!
五、基本语法
1、select查询语句
select table_name from user_tables;(查询系统表)
以上的查询语句就是查询本用户下所拥有的所有表的表名。
投影操作,只查看选择的字段的信息。
选择操作,查看字段中的特定某些信息。
联接操作,多表查询,通过表间连接,查寻出多表中的信息
(1)select table_name from user_tables;(查询系统表)
以上的查询语句就是查询本用户下所拥有的所有表的表名。
(2)sqlplus的buffer中会缓存最后一条sql语句,可以使用"/"来执行这最后一条sql语句,也可以使用
edit命令来编辑最后一条sql语句。
l命令(list)(sqlplus命令)可以显示buffer中最后一条命令。
sqlplus命令可以缩写
(3)desc [表名]
这是一条sqlplus命令,注意他不是sql语句,这条命令用于查看表的结构。descript的缩写
[字段名] [字段的类型],这是使用完desc命令后显示的表结构。
(4)select [表的字段名1],[表的字段名2], ... from 表名;
select * from 表名; 查寻表中所有字段的信息
(5)关键字不等拆分,sql语句,以及表名,字段名是大小写不敏感的。
sql语句要以";"结尾,来表示sql语句结束,如果不加";"系统不会执行此条sql语句,并提示。
在Oracle中字符显示是左对齐,数值右对齐。
(6)在select 语句中可以使用数学表达式。
select [表达式(必须包含本表字段名)],[...],.... from 表名;
运算的优先级的先乘除后加减,同级自左向右运算,括号改变优先级。
(7)别名
select [字段名或表达式] ["别名"],[...] ["..."],.... from 表名;
可以通过在字段名或表达式后加空格"别名",可以给列,或者表达式结果其别名。
表达别名必须加双引号。
(8)字符串拼接使用||符号
select 目标字段名||" "||目标字段名 from 表名;
注意:在Oracle中的字符串要用'..'包含
别名中需要使用空格,或是大小写敏感时需要用".."包含。
练习:
自己写一条SQL语句,执行的结果是select * from ...;
其中...是每张系统表的表名
即在每张系统表的表名前加“select * from” ,后加“;”
select 'select * from '||table_name||';' from user_tables;
2、处理错误
(1)!oerr ora [错误号] ,系统可以显示错误的原因和如何修改。如果命令错误输入可以使用edit或ed来修改输入错误。
实际上是在编辑缓存文件中的最后一条sql语句。
也可以使用 (change) c /错误字段/正确字段,来进行替换操作进行修改。
只有在Linux平台使用
! 相当于 host ,没有断连接,只是切换了一下,执行shell命令
(2)edit命令来编辑最后一条sql语句。
3、sqlplus设置
set pause on 回车响应,分屏显示,只在本会话中有效
set pause off 关闭分屏显示。
set pause "..." 设置分屏显示的提示信息。
set pause on 先输出提示信息,回车响应,分屏显示
set head off 提头输出关闭
set feed off 结尾输出关闭
set echo off 回写关闭
spool 文件名.sql 写入指定文件
spool off 关闭写入。
4、sql脚本
也就是在文件中写有sql语句的文件,可以在sqlplus中运行。
引入sql脚本
sqlplus 用户名/密码 @sql脚本 (注意:在用户名密码输入结束后一定要加空格然后再写@sql脚本)
在脚本中最后一行写上“exit”,则运行完脚本以后,回到shell上
5、
Oracle中的空值 空值会当无穷大处理,其实空值根本就不会存储,只是看作是无穷大。
Oracle中控制处理函数 NVL(字段名,值),这个字段中的空值替换为指定值,如果不为空,则会返回其原值。
例:select (salary*12)*(NVL(commission_pct,0)/100+1) salary,first_name from s_emp;
distinct关键字,去掉重复行(这个关键字会触发排序操作)
例: select distinct dept_id,title from s_emp;
dept_id与title的联合不唯一
注意:distinct,关键字之后会对from之前的字段进行排重操作。
6、column命令 --- sqlplus命令
column命令 列格式的定义
column 目标列名 查看这个类是否定义了格式
column 目标列名 format a.. 设置列宽。
column last_name heading 'Employee|Name' FORMAT A15
设置题头
这其中的'|'是换行符
column salary justify left format $99,990.00
定义数字显示格式
注意:如果不满足显示的格式,就会把数据显示为"#"
column salary justify left format $00,000.00
会出现$00,928.00 ,用0补齐
column 列名 clear (清除列格式定义)
注意:只有sqlplus命令才有简写,并且在使用sqlplus命令时结尾也不能加分号。
六、选择操作
1、order by
排序子句 ASC(默认,升序) DESC(降序)
order by 目标列名(别名) 排序顺序(不写排序顺序,会默认为升序排序)
例:select first_name from s_emp order by first_name;
select first_name from s_emp order by first_name desc;
注意:升序空值在结果的末尾,降序空值在结果的最前面。
2、where子句
where子句使用在 select ... from ... 后面,用来选择所需(符合条件的)的记录
where后面跟的是表达式 也就是 XXX=XXX, XXX between X and X ,XXX in(X,X,X)
like '...' 通配查询
between ... and ... ,表示结果在这之间,between and是一个闭区间,
也就相当于... <= ... and ... >= ... 。
!=,<>,^=,这三个都标识不等于,<=,>=,=,这些运算符都可以使用。
... in (va1,val2,...) 判断结果是否在这个枚举中存在
like '...' 字符串通配查询,'%'表示多个字符,'_',表示一个字符。
注意:转义的用法:like ‘S\_%’ escape ‘\’
... and ... 表示只有两个条件同时满足
... or ... 表示条件只要满足其中只一就可以
all ... 是要求都满足条件。
not .....,则是可以与以上的条件产生反效果。
空值会对not in造成影响,也就是不等于任何值,但是空值例外。
... is null 使用来判断值是否为空。
注意:Oracle中的字符串是严格区分大小写的。
(1)注意数据类型,数字类型直接写,字符用'......' ,缺省格式的Date可以用'......',只有别名
才用" "包含。
(2)选择合适的运算符
七、单行函数
1.字符函数
字符是大小写敏感的
转小写 lower(字段名) --- 其中的参数可以是一个字符串常量或是一个字段名
转大写 upper(字段名)
首字母大写 initcap(字段名)
字符串拼接 concat(字段1, 字段2)
截取子串 substr(字段名, 起始位置,取字符个数)
al表,是专门用于函数测试和运算的,他只有一条记录
字符串拼接 concat(...,....)
求指定子串 substr(...,起始位置,取字符个数)
可以使用"-"表示从右向左取,取的时候可以从左往友取。
例:select substr(first_name,-2,2) sub from s_emp;(取后两个)
select substr(first_name,2,2) sub from s_emp;(取前两个)
2,数值函数
四舍五入 round(数据,保留小数点后几位)
可以用负数表示小数点前,0,表示小数点后第一位,也就是保留个位,-1表示个位(保留到十 位)。
例:select round(15.36,1) from al;
截取数字函数 trunc(数据,保留的位数(小数点后位数)) 截取个位之后补0
例:select trunc(123.456,1) from al;
3,日期函数
日期格式,
全日期格式 世纪信息,年月日,时分秒。
缺省日期格式,日-月-年 dd-mon-rr
修改当前会话的日期格式,会按照指定的格式输出日期
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
返回当前日期 sysdate
例:select sysdate from al;
select sysdate+1 from al; 获得明天的日期,加1,单位是天
日期是格式敏感的
求两个日期间相隔了多少个月 months_between(date1,date2)
加减指定数量的月份 add_months(date,月数),月数可以为负,负值就是减去相应的月数。
从date日期开始的第一个星期五 next_day(date,FriDay)
返回月末的日期 last_day(date)
截取日期 trunc(date,'年或月或日或时分秒')
例:select next_day(sysdate,2) from al;
例:select trunc(add_months(sysdate,1),'month') from al;
ROUND('25-MAY-95','MONTH') 01-JUN-95
ROUND('25-MAY-95 ','YEAR') 01-JAN-95
TRUNC('25-MAY-95 ','MONTH') 01-MAY-95
TRUNC('25-MAY-95 ','YEAR') 01-JAN-95
练习:
返回下个月的第一天的日期
select round(last_day(sysdate),'MONTH') from al;
select add_months(trunc(sysdate,'MONTH'),1);
4,不同数据类型间转换函数
将日期转成字符 tochar(date,'日期格式')
日期格式要用有效格式,格式大小写敏感 'yyyy mm dd hh24:mi:ss',
'year'(全拼的年),'mm'(数字表示的月) 'month'(全拼的月),'day'(星期的全拼),'ddspth' (日期的全拼) 'yy mm dd'
例:select to_char(sysdate,'yyyy mm dd hh24:mi:ss')from al;
将字符转换成数字 to_number('...')
将数字转字符to_char(number,'fmt') fmt是数字格式
将字符串转成日期 to_date('...','日期格式')
例:select to_char(to_date('2006 11 03','yyyy mm dd'),'dd-month-yy') from al;
1、等值连接
select [表别名1.字段名1],[表别名2.字段名2],...
from 表1 表别名1 ,表2 表别名2
where 表别名1.字段名3=表别名2.字段名4;
表连接时,当表与表之间有同名字段时,可以加上表名或表的别名,加以区分,使用时要用
表名.字段名或表别名.字段名(列名)。当表的字段名是唯一时,可以不用加上表名或表的别名。
注意:当为表起了别名,就不能再使用表名.字段名。
例:select a.first_name,a.last_name,b.name
from s_emp a,s_dept b
where a.dept_id=b.id;
2、非等值连接
select [表别名1.字段名1],[表别名2.字段名2],...
from 表1 表别名1 ,表2 表别名2
where 表别名1.字段名3 ..... 表别名2.字段名4
....可以使比较运算符,也可以使其他的除了'='的运算符
例:select e.ename, d.grade,e.sal
from emp e,salgrade d
where e.sal between d.losal and d.hisal;
3、自连接
用别名把一张表中的数据分成两部分,然后在使用条件过滤。
select [表别名1.字段名1],[表别名2.字段名2],...
from 表1 表别名1 ,表1 表别名2
where 表别名1.字段名3=表别名2.字段名4;
例:select a.first_name ename,b.first_name cname
from s_emp a,s_emp b
where a.manager_id=b.id;
以上所提到的表连接,都叫做内连接,严格匹配两表的记录。
4、外连接
会使用一方表中的所有记录去和另一格表中的记录按条件匹配,空值也会匹配,这个表中的所有记录都会显示,数据库会模拟出记录去和那些不匹配的记录匹配。
例:select a.first_name enamei,a.id,b.first_name cname,b.id
from s_emp a,s_emp b
where a.manager_id=b.id(+);
即用a表中的数据去匹配b表的,若b表中有null,系统模拟纪录与其匹配
注意:要把那一方的记录全部都显示出来,还有注意条件(+)跟在要全部选出的对端。
外连接的应用:
列出哪个部门没有员工
select e.deptno,d.deptno
from emp e,dept d
where e.deptno(+)=d.deptno
and e.deptno is null;
三、组函数
group 组
group by 分组子句,按指定的分组规则分组 ,这个group by 子句可以跟在 select 语句后或是 having后面。
group by子句也会出发排序操作,会按分组字段排序。
select [组函数或分组的字段名] ,... from 表名 group by [字段名1],[字段名2],.....;
例:select avg(salary) from s_emp group by dept_id;
注意:组函数可以处理一组数据,返回一个值。
组函数会忽略空值。
avg(..),求平均值,sum(..),求和 这两个函数的参数只能是number型的。
以下所提到的函数可以使用任意类型做参数。
count(..),用来统计记录数,可以使用排重命令。count(...)默认使用的是all。
max(..),min(..)求最大值和最小值,
count(*),统计表中记录数。
例:select max(b.name),avg(a.salary), max(c.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.dept_id;
注意:只要写了group by子句,
*** select后就只能用group by后的字段或者是组函数。 ***
where子句只能够过滤记录,放单行函数。
having子句可以过滤组函数结果或是分组的信息,且写在group by子句后。
例:
select max(b.name),avg(a.salary), max(c.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.id
having sum(a.salary)>4000;
column 也可以定义有别名的列的格式。
column "别名" 格式定义
注意:要先过滤掉不需要的记录,然后再进行分组操作,提高效率。
四、子查询
子查询,就是可以嵌在任何的sql语句中的select语句。
在select语句中嵌套子查询时,会先执行子查询。一般的会将子查询放在运算符的右边。
注意:在使用子查询时,要注意这个运算符是单行的(也就是只能是单值),还是多行运算符(范围,多值,in)。
配合使用子查询返回的结果必须符合运算符的用法。
例:
select first_name,title
from s_emp
where title=any(select title from s_emp
where last_name='Smith')
and upper(last_name)!='SMITH';
select first_name,title
from s_emp
where title in (select title from s_emp
where last_name='Smith')
and upper(last_name)!='SMITH';
五、将业务需求转换成可操作的表
一: 需求分析
二: 画E-R图
三: 转换成表关系
四: 割接(新老系统交接)
五:
E-R图属性:
* 为强制且非空属性
o 可选属性(可以有值也可以没有)
#* 表示此属性唯一且非空
实体关系:
mastbean maybean
数量关系: 多对一关系
一对多关系
一对一关系
多对多关系
第一范式,所有的属性都必须是单值,也就是属性只表示单一的意义。(记录可以重复,没有任何限制)
第二范式,属性要求唯一且非空,(记录不可重复,但是数据可能会出现冗余)。
第三范式,非主属性只能依赖于主属性,不能依赖于其他非主属性。(解决数据冗余问题)
六、约束
约束是针对表中的字段进行定义的。
primary key (主键约束 PK)保证实体的完整性,保证记录的唯一
主键约束,唯一且非空,并且每一个表中只能有一个主键,有两个字段联合作为主键,只有两个字段放在一起唯一标识记录,叫做联合主键。
foreign key (外建约束 FK)保证引用的完整性,
外键约束,外键的取值是受另外一张表中的主键或唯一值得约束,不能够取其他值,只能够引用主键会唯一键的值,被引用的表,叫做parent table(父表),引用方的表叫做child table(子表),要想创建子表,就要先创建父表,后创建子表,记录的插入也是如此,先父表后子表,删除记录,要先删除子表记录,后删除父表记录,要修改记录,如果要修改父表的记录要保证没有被子表引用。要删表时,要先删子表,后删除父表。
unuque key(唯一键),值为唯一
index(索引)是数据库特有的一类对象,view(示图)
典型的一对多 class 对应多个学生。
student table class table
______________________________ _________________________
| id | name | address| class_id| | id |class_desc|class_num|
|(PK)|______|________|___(FK)__| |(pk)|__________|_________|
| | | | | | | | |
一对一
student tabel shenfenzheng table
____________________ _________________________________
| id | name | address| | s_id |shenfen_desc|shenfen_num|
|(PK)|______|________| |(PK,FK)|____________|___________|
| | | | | | | |
多对多
student tabel zhongjian table kecheng table
____________________ _________________________________ __________________
| id | name | address| | s_id |shenfen_desc|shenfen_num| | kid | kechengname|
|(PK)|______|________| |(FK,FK)|____________|___________| | (PK)|____________|
| | | | |联合主键| | | | | |
引用对方表的主键,当作本身的主键,所以这个表的主键,既是主键又是外建
建表和其他相关操作
DDL语句
创建表:
create table 表名 ( 字段名1 类型(数据长度)(default ...) 约束条件, 字段名2 类型(数据长度) 约束条件 );
Oracle数据库中的数据类型
varchar(长度),可变长字符串,char(长度) 定长
number(..,..),number 表示浮点数,或者是整数
long 大对象,clog 字符的大对象,相当于文本文件在表中只存放一个相当于只针对值
blog 二进制的大对象,也是以相当于指针的形式存放的。
primary key约束:
主键约束的定义:
第一种定义形式:
create table test(c number primary key ); 列级约束
第二种定义形式:
create table test(c number , primary key(c) ) ; 表级约束
create table test( c1 number constraints pkc1 primary key ); 此约束有名字: pkc1
create table test(c number , c2 number , primary key (c ,c1) ) ; 用表级约束可以实现联合主键
foregin key (fk) 外键约束:
(先定义父表,再定义子表)
carete table parent(c1 number primary key );
create table child (c number primary key , c2 number references parent(c1));
或表级约束定义:
create table child( c number primary key , c2 number , foreign key(c2) references parent(c1));
如果两个字段都为唯一且非空,这时可以定义成UK+NOT NULL
(PK或UK)一对多(FK)
(PK+UK)一对一(FK) 或 (PK)一对一(PK)
多对对多关系,一般都通过一张中间表来分解成两个一对多的表
建立表
create table[schema]table
schema: 一个用户对应一个schema 不同用户下的表不能互相查看
select count(*) from s_dept; <===> select count(*) from sd0611.s_dept;
一个表中只能存储一个LONG类型
CLOB 存储大的文本对象
BLOB 存储大的二进制对象
create table test(c1 number primary key); 设置主键
create table test(c1 number constraints test_c1 primary key); 定义约束名,默认约束名为SYS_ 在列后面定义约束称为列级约束
create table test(c1 number primary key(c1)); 所有列定义完后再定义约束称为表级约束(能定义联合主键)
cretae table test(c1 number,c2 number,priary key(c1,c2)); 定义联合主键
create table child(c1 number primary key); 先要定义父表
create table child(c1 number primary key, c2 number references parent(c1)); 然后定义子表 references parent定义外键
create table child(c1 number primary key, c2 number references parent(c1) on delete cascate); on delete cascate为级联删除
create table child(c1 number primary key, c2 number references parent(c1) on delete set null); on delete set null删除后将外键置空
create table child (c1 number primary key, c2 number,foreignkey(c2) references parent(c1));
二、约束
1、非空约束(not null)
这是一个列级约束
在建表时,在数据类型的后面加上 not null ,也就是在插入时不允许插入空值。
例:create table student(id number primary key,name varchar2(32) not null,address varchar2(32));
2、unique 唯一约束
唯一约束,是会忽略空值的,唯一约束,要求插入的记录中的值是为一的。
例:create table student(id number,name varchar2(32),address varchar2(32),primary key (id),unique (address));
如果创建一个uk,系统自动建一个唯一索引
3、pk、uk
Oralce支持级联删除,不支持级联更新
4、check约束
检查约束,可以按照指定条件,检查记录的插入。check中不能使用尾列,不能使用函数,不能引用其他字段。
例:create table sal (a1 number , check(a1>1000));
Ⅶ 获取当前时间减去10分钟的话SQL语句怎么写
对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描述见7.3.6 日期和时间类型。
这里是一个使用日期函数的例子。下面的查询选择了所有记录,其date_col的值是在最后30天以内:
mysql> SELECT something FROM table
WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;
DAYOFWEEK(date)
返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六)。这些索引值对应于ODBC标准。
mysql> select DAYOFWEEK('1998-02-03');
-> 3
WEEKDAY(date)
返回date的星期索引(0=星期一,1=星期二, ……6= 星期天)。
mysql> select WEEKDAY('1997-10-04 22:23:00');
-> 5
mysql> select WEEKDAY('1997-11-05');
-> 2
DAYOFMONTH(date)
返回date的月份中日期,在1到31范围内。
mysql> select DAYOFMONTH('1998-02-03');
-> 3
DAYOFYEAR(date)
返回date在一年中的日数, 在1到366范围内。
mysql> select DAYOFYEAR('1998-02-03');
-> 34
MONTH(date)
返回date的月份,范围1到12。
mysql> select MONTH('1998-02-03');
-> 2
DAYNAME(date)
返回date的星期名字。
mysql> select DAYNAME("1998-02-05");
-> 'Thursday'
MONTHNAME(date)
返回date的月份名字。
mysql> select MONTHNAME("1998-02-05");
-> 'February'
QUARTER(date)
返回date一年中的季度,范围1到4。
mysql> select QUARTER('98-04-01');
-> 2
WEEK(date)
WEEK(date,first)
对于星期天是一周的第一天的地方,有一个单个参数,返回date的周数,范围在0到52。2个参数形式WEEK()允许
你指定星期是否开始于星期天或星期一。如果第二个参数是0,星期从星期天开始,如果第二个参数是1,
从星期一开始。
mysql> select WEEK('1998-02-20');
-> 7
mysql> select WEEK('1998-02-20',0);
-> 7
mysql> select WEEK('1998-02-20',1);
-> 8
YEAR(date)
返回date的年份,范围在1000到9999。
mysql> select YEAR('98-02-03');
-> 1998
HOUR(time)
返回time的小时,范围是0到23。
mysql> select HOUR('10:05:03');
-> 10
MINUTE(time)
返回time的分钟,范围是0到59。
mysql> select MINUTE('98-02-03 10:05:03');
-> 5
SECOND(time)
回来time的秒数,范围是0到59。
mysql> select SECOND('10:05:03');
-> 3
PERIOD_ADD(P,N)
增加N个月到阶段P(以格式YYMM或YYYYMM)。以格式YYYYMM返回值。注意阶段参数P不是日期值。
mysql> select PERIOD_ADD(9801,2);
-> 199803
PERIOD_DIFF(P1,P2)
返回在时期P1和P2之间月数,P1和P2应该以格式YYMM或YYYYMM。注意,时期参数P1和P2不是日期值。
mysql> select PERIOD_DIFF(9802,199703);
-> 11
DATE_ADD(date,INTERVAL expr type)
DATE_SUB(date,INTERVAL expr type)
ADDDATE(date,INTERVAL expr type)
SUBDATE(date,INTERVAL expr type)
这些功能执行日期运算。对于MySQL 3.22,他们是新的。ADDDATE()和SUBDATE()是DATE_ADD()和DATE_SUB()的同义词。
在MySQL 3.23中,你可以使用+和-而不是DATE_ADD()和DATE_SUB()。(见例子)date是一个指定开始日期的
DATETIME或DATE值,expr是指定加到开始日期或从开始日期减去的间隔值一个表达式,expr是一个字符串;它可以以
一个“-”开始表示负间隔。type是一个关键词,指明表达式应该如何被解释。EXTRACT(type FROM date)函数从日期
中返回“type”间隔。下表显示了type和expr参数怎样被关联: type值 含义 期望的expr格式
SECOND 秒 SECONDS
MINUTE 分钟 MINUTES
HOUR 时间 HOURS
DAY 天 DAYS
MONTH 月 MONTHS
YEAR 年 YEARS
MINUTE_SECOND 分钟和秒 "MINUTES:SECONDS"
HOUR_MINUTE 小时和分钟 "HOURS:MINUTES"
DAY_HOUR 天和小时 "DAYS HOURS"
YEAR_MONTH 年和月 "YEARS-MONTHS"
HOUR_SECOND 小时, 分钟, "HOURS:MINUTES:SECONDS"
DAY_MINUTE 天, 小时, 分钟 "DAYS HOURS:MINUTES"
DAY_SECOND 天, 小时, 分钟, 秒 "DAYS HOURS:MINUTES:SECONDS"
MySQL在expr格式中允许任何标点分隔符。表示显示的是建议的分隔符。如果date参数是一个DATE值并且你的计算仅仅
包含YEAR、MONTH和DAY部分(即,没有时间部分),结果是一个DATE值。否则结果是一个DATETIME值。
mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
-> 1998-01-01 00:00:00
mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
-> 1998-01-01
mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
-> 1997-12-31 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL 1 SECOND);
-> 1998-01-01 00:00:00
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL 1 DAY);
-> 1998-01-01 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL "1:1" MINUTE_SECOND);
-> 1998-01-01 00:01:00
mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
INTERVAL "1 1:1:1" DAY_SECOND);
-> 1997-12-30 22:58:59
mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
INTERVAL "-1 10" DAY_HOUR);
-> 1997-12-30 14:00:00
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
-> 1997-12-02
mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
-> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
-> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
-> 20102
如果你指定太短的间隔值(不包括type关键词期望的间隔部分),MySQL假设你省掉了间隔值的最左面部分。例如,
如果你指定一个type是DAY_SECOND,值expr被希望有天、小时、分钟和秒部分。如果你象"1:10"这样指定值,
MySQL假设日子和小时部分是丢失的并且值代表分钟和秒。换句话说,"1:10" DAY_SECOND以它等价于"1:10" MINUTE_SECOND
的方式解释,这对那MySQL解释TIME值表示经过的时间而非作为一天的时间的方式有二义性。如果你使用确实不正确的日期,
结果是NULL。如果你增加MONTH、YEAR_MONTH或YEAR并且结果日期大于新月份的最大值天数,日子在新月用最大的天调整。
mysql> select DATE_ADD('1998-01-30', Interval 1 month);
-> 1998-02-28
注意,从前面的例子中词INTERVAL和type关键词不是区分大小写的。
TO_DAYS(date)
给出一个日期date,返回一个天数(从0年的天数)。
mysql> select TO_DAYS(950501);
-> 728779
mysql> select TO_DAYS('1997-10-07');
-> 729669
TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。
FROM_DAYS(N)
给出一个天数N,返回一个DATE值。
mysql> select FROM_DAYS(729669);
-> '1997-10-07'
TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。
DATE_FORMAT(date,format)
根据format字符串格式化date值。下列修饰符可以被用在format字符串中: %M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。)
%Y 年, 数字, 4 位
%y 年, 数字, 2 位
%a 缩写的星期名字(Sun……Sat)
%d 月份中的天数, 数字(00……31)
%e 月份中的天数, 数字(0……31)
%m 月, 数字(01……12)
%c 月, 数字(1……12)
%b 缩写的月份名字(Jan……Dec)
%j 一年中的天数(001……366)
%H 小时(00……23)
%k 小时(0……23)
%h 小时(01……12)
%I 小时(01……12)
%l 小时(1……12)
%i 分钟, 数字(00……59)
%r 时间,12 小时(hh:mm:ss [AP]M)
%T 时间,24 小时(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM
%w 一个星期中的天数(0=Sunday ……6=Saturday )
%U 星期(0……52), 这里星期天是星期的第一天
%u 星期(0……52), 这里星期一是星期的第一天
%% 一个文字“%”。
所有的其他字符不做解释被复制到结果中。
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
-> 'Saturday October 1997'
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
'%D %y %a %d %m %b %j');
-> '4th 97 Sat 04 10 Oct 277'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
'%H %k %I %r %T %S %w');
-> '22 22 10 10:23:00 PM 22:23:00 00 6'
MySQL3.23中,在格式修饰符字符前需要%。在MySQL更早的版本中,%是可选的。
TIME_FORMAT(time,format)
这象上面的DATE_FORMAT()函数一样使用,但是format字符串只能包含处理小时、分钟和秒的那些格式修饰符。
其他修饰符产生一个NULL值或0。
CURDATE()
CURRENT_DATE
以'YYYY-MM-DD'或YYYYMMDD格式返回今天日期值,取决于函数是在一个字符串还是数字上下文被使用。
mysql> select CURDATE();
-> '1997-12-15'
mysql> select CURDATE() + 0;
-> 19971215
CURTIME()
CURRENT_TIME
以'HH:MM:SS'或HHMMSS格式返回当前时间值,取决于函数是在一个字符串还是在数字的上下文被使用。
mysql> select CURTIME();
-> '23:50:26'
mysql> select CURTIME() + 0;
-> 235026
NOW()
SYSDATE()
CURRENT_TIMESTAMP
以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回当前的日期和时间,取决于函数是在一个字符串还是在数字的
上下文被使用。
mysql> select NOW();
-> '1997-12-15 23:50:26'
mysql> select NOW() + 0;
-> 19971215235026
UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)
如果没有参数调用,返回一个Unix时间戳记(从'1970-01-01 00:00:00'GMT开始的秒数)。如果UNIX_TIMESTAMP()用一
个date参数被调用,它返回从'1970-01-01 00:00:00' GMT开始的秒数值。date可以是一个DATE字符串、一个DATETIME
字符串、一个TIMESTAMP或以YYMMDD或YYYYMMDD格式的本地时间的一个数字。
mysql> select UNIX_TIMESTAMP();
-> 882226357
mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
-> 875996580
当UNIX_TIMESTAMP被用于一个TIMESTAMP列,函数将直接接受值,没有隐含的“string-to-unix-timestamp”变换。
FROM_UNIXTIME(unix_timestamp)
以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回unix_timestamp参数所表示的值,取决于函数是在一个字符串
还是或数字上下文中被使用。
mysql> select FROM_UNIXTIME(875996580);
-> '1997-10-04 22:23:00'
mysql> select FROM_UNIXTIME(875996580) + 0;
-> 19971004222300
FROM_UNIXTIME(unix_timestamp,format)
返回表示 Unix 时间标记的一个字符串,根据format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条
目同样的修饰符。
mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
'%Y %D %M %h:%i:%s %x');
-> '1997 23rd December 03:43:30 x'
SEC_TO_TIME(seconds)
返回seconds参数,变换成小时、分钟和秒,值以'HH:MM:SS'或HHMMSS格式化,取决于函数是在一个字符串还是在数字
上下文中被使用。
mysql> select SEC_TO_TIME(2378);
-> '00:39:38'
mysql> select SEC_TO_TIME(2378) + 0;
-> 3938
TIME_TO_SEC(time)
返回time参数,转换成秒。
mysql> select TIME_TO_SEC('22:23:00');
-> 80580
mysql> select TIME_TO_SEC('00:39:38');
-> 2378
SELECT DATE_SUB(now(),
INTERVAL "0 0:10:0" DAY_SECOND);