标签(空格分隔): 数据库
参考书:《SQL入门经典–第五版》《Oracle 11g 权威指南》
作者:美国人 谷长勇
出版社: 人民邮电出版社 电子工业出版社 2008年左右出版
信息存放在二维表(table)中。一个关系数据库包含多个数据表。每一个表包含行(记录)和列(字段)。
表之间相互关联。主键(PrimaryKey)和外键(ForeignKey)所体现的参照关系实现。
数据库除了表,还包含:视图、存储过程、索引等。
相关概念:
关键字(Key),是关系模型中的逻辑结构,分为主键外键。
2.2.2.1 定长字符串
2.2.2.2 变长字符串
区分:VARCHAR(n)、VARCHAR2(n)和nvarchar(n)、VARYING(n)
VARCHAR(n)
VARCHAR2(n)
NVARCHAR(n)
VARBINARY
注意:
2.2.2.3 直义字符串
2.2.2.1 大对象类型 BLOB TEXT
2.2.2.2 数值类型
分类:
下面是SQL数值的标准.
BIT(n)
BIT VARYING(n)
Decimal(p,s)
INTEGER
SmallInt
BigInt
Float(p,s)
Double PRECISION(p,s)
Real(s)
2.2.2.2 小数类型
2.2.2.3 整数类型
2.2.2.4 浮点数
######2.2.3日期和时间类型
######2.2.4NULL数据类型
######2.2.5布尔值
#####2.2.6自定义数据类型
CREATE TYPE PERSON AS OBJECT
(NAME VARCHAR(30),
SSN VARCHAR(9));
然后可以像下面这样引用自定义类型
CREATE TABLE EMP_PAY
(EMPLOYEE PERSON ,
SALARY DECIMAL(10,2) ,
HIRE_OATE DATE);
表EMP_PAY 第一列EMPLOYEE的类型是PERSON,这正是在前面创建的自定义类型。
#####2.2.7域
像下面这样就可以创建域
CREATE DOMAIN MONEY_D AS NUMBER(8 ,2);
像下面这样为域添加约束
ALTER DOMAIN MONEY_D AS NUMBER(8,2)
ADD CONSTRAINT MONEY_CON1
CHECK (VAlUE>5);
然后像下面这样引用域
CREATE TABlE EMP_PAY
(EMP_ID NUMBER(9),
EMP_NAME VACHAR2(30),
PAY_RATE MONEY_D):
create table tabelname(
columnName dataType[length] [Not NULL],
columnName dataType [Not NULL],
columnName dataType [Not NULL]
);
alter table table_name [modify] [column column_name] [datatype | null
not null] [restrict|cascade]
[drop] [constraint_constraint_name]
[add] [column] column definition
属性:
列的数据类型
列的长度、有效位数或者标度
列是否为空
ALTER TABLE EMPLOYEE_TBL MODIFY EMP_ID VARCHAR2(10 BYTE);
- 删除表中的字段
格式: alter table 表名 drop column 字段名称;
需求: 删除person表格中的name字段
alter table person drop column name;
- 添加表中的字段
格式: alter table 表名 add 字段名 字段类型(长度);
需求: 向person表中 添加一个name字段 ,类型为varchar2长度为10
alter table person add name varchar2(10);
CREATE TABLE TEST_ INC FlEMENT(
ID SERIAL,
TEST_NAME VAACHAR(20));
comment on column 表名.字段名 is 'XX';
Oracle:使用Sequence对象和触发器来实现类似的效果。22章会讲。可以直接插入内容,不为自动增加的列制定值。
4、修改表
比较复杂的情况,可以删除表重新建。
语法:
create table new table name as
select [ *|column1, column2 ]
from table_name
[ where ]
实例:
--原先的表--
SELECT * FROM PRODUCTS_TBL ;
--新生成的表--
CREATE TABLE products_tbl_test AS SELECT * FROM products_tbl ;
-- 新生成的表跟原表一样的属性 但是索引可能有不同--
SELECT * FROM products_tbl_test;
drop table table_name [restrict|cascade]
1、隐含约束:建表过程中指定的
create table table_name(
column_name datatype(length) not null primary key,
XXX
);
2、建表语句字段后创建
create table table_name(
column_name datatype(length) not null,
XXX,
primary key(column_name1 [,column_name2])
);
3、修改表结构
ALTER TABLE PRODUCT_TST
ADD CONSTRAINT PRODUCTS_PK PRIMARY KEY (PROD_ID , VEND_ID);
--唯一约束 UNIQUE--
CREATE TABLE EMPLOYEE_TBL_UNIQUE
(
EMP_ID VARCHAR(9) NOT NULL,
LAST_NAME VARCHAR(15) NOT NULL,
FIRST_NAME VARCHAR(15) NOT NULL,
MIDDLE_NAME VARCHAR(15),
ADDRESS VARCHAR(30) NOT NULL,
CITY VARCHAR(15) NOT NULL,
STATE CHAR(2) NOT NULL,
ZIP INTEGER NOT NULL,
PHONE CHAR(10) UNIQUE, --唯一约束--
PAGER CHAR(10),
CONSTRAINT EMP_PK_UNIQUE PRIMARY KEY (EMP_ID)
);
-- 外键约束--
CREATE TABLE EMPLOYEE_PAY_TST(
EMP_ID VARCHAR(9) NOT NULL,
POSITION VARCHAR2(15) NOT NULL,
DATA_HIRE DATE NULL,
PAY_RATE NUMBER(4,2) NOT NULL,
DATE_LAST_RAISE DATE NULL,
--子表EMPLOYEE_PAY_TST
CONSTRAINT EMP_ID_PK FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEE_TBL (EMP_ID)
);
或者ALTER向表里添加外键
alter table employee_pay_tbl add constraint id_fk foreign key(emp_id) references EMPLOYEE_TBL (EMP_ID);
CREATE TABLE employee_check_tst
(EMP_ID CHAR(9) NOT NULL,
EMP_NAME VARCHAR2(40) NOT NULL,
EMP_ST_ADDR VARCHAR2(20) NOT NULL,
EMP_CITY VARCHAR2(15) NOT NULL,
EMP_ST CHAR(2) NOT NULL,
EMP_ZIP NUMBER(5) NOT NULL,
EMP_PHONE NUMBER(10) NULL,
EMP_PAGER NUMBER(10) NULL,
PRIMARY KEY(EMP_ID),
CONSTRAINT CHE_EMP_ZIP CHECK( (EMP_ZIP = '46234') )
);
--确保了输入到这个表里的全部雇员的 EMP_ZIP代码都是 "46234"
-- 删除约束
ALTER TABLE TABLE_NAME DROP CONSTRAINT CONSTRAINT_NAME;
参考链接: https://www.cnblogs.com/1906859953Lucas/p/8299959.html
1. 全字段添加
INSERT INTO TABLE_NAME VALUES('value1','value2',[NULL]);
格式: insert into 表名 values(数据列表);
数据列表 : 表示的是一个数据组,数据的顺序按照创建表格时的字段顺序传入,不同字段的值使用英文逗号隔开,字符串用单引号
2. 选择字段添加
INSERT INTO TABLE_NAME('COLUMN1','COLUMN2',...) VALUES('value1','value2',...);
格式: insert into 表名(字段列表) values(数据列表);
字段列表可以任意排列 , 多个字段名之间使用英文逗号隔开,数据列表的顺序, 参照字段列表
insert into table_name [('column1','column2')]
select [ *|('column1','column2') ] from table_name
[ where condition[s] ];
insert into table_A select * from table_b; --必须保证A和B表结构一致
这两条语句是一样的
--语句A
INSERT INTO ORDERS_TBL (ORD_NUM, CUST_ID, PROD_ID, QTY, ORD_DATE) VALUES ('23A16','109', '7725',2, NULL);
--语句B
INSERT INTO ORDERS_TBL (ORD_NUM, CUST_ID, PROD_ID, QTY) VALUES ('23A16','109', '7725',2);
update table_name set colunm_name = 'value' [where conditions];
不加where条件会更新所有的数据。
update table_name set colunm_name1 = 'value',
[colunm_name2 = 'value', colunm_name3 = 'value']
[where conditions];
不加where条件会更新所有的数据。
delete from table_name [where conditions]
commit [work];
rollback [work];
savepoint savepoint_name ;
rollback to savepoint_name ;
savepoint sp1;
savepoint create;
SQL_X1;
savepoint sp2;
savepoint create;
SQL_X2;
rollback to sp1;
release savePoint savepoint_name ;
SET TRANSACTION READ WRITE;--查询和操作,对数据库对象加锁,保证数据完整性。
SET TRANSACTION READ ONLY; --只读 适合生成报告,速度快。
SELECT [ *|ALL|DISTINCT COLUMN1, COLUMN2,]
FROM TABLE1 [, TABLE2 1];
from 表1[,表2]
SELECT [ *|ALL|DISTINCT COLUMN1, COLUMN2,]
FROM TABLE1 [, TABLE2 1]
[ WHERE CONDITION1|EXPRESSION1 [ AND|OR CONDITION2|EXPRESSION2] ];
SELECT ROWID, TO_CHAR(COST,'999990.000') ,SUBSTR( TO_CHAR(COST,'999990.000'),-4,2) FROM PRODUCTS_TBL ORDER BY SUBSTR( TO_CHAR(COST,'999990.000'),-2,2);
SELECT [ *|ALL|DISTINCT COLUMN1, COLUMN2,]
FROM TABLE1 [, TABLE2 1]
[ WHERE CONDITION1|EXPRESSION1 [ AND|OR CONDITION2|EXPRESSION2]
ORDER BY COULMN1|INTEGER [ASC\DESC] ];
--1代表第一个字段 按照prod_desc排序
select prod_desc, prod_id,cost from products_tbl where cost < 200 order by 1;
ORDER BY A,B
select count(*) from 表名 表里全部数据行数
select count(非空字段)from 表名 =表全部记录
select count(可以为空字段) from 表名 不含有全部表记录
select count(DISTINCT 字段) from 表名 去重
SELECT 字段名 FROM 规划名|用户名.表名
语法格式:
select 查询的列或者表达式1 别名,查询的列或者表达式2 别名 from 表名;
单个列只允许存在一个别名!
需求: 查询年薪, 并且给年薪字段添加别名:
-- 别名
--select last_name,salary*13 yearly salary from s_emp;--报错 ORA-00933: ORA-00923: 未找到要求的 FROM 关键字 yearly salary改成yearly_salary
--select last_name,salary*13 as '年薪' from s_emp;--不可以 ORA-00923: 未找到要求的 FROM 关键字
select last_name,salary*13 yearlySalary from s_emp;--可以
select last_name,salary*13 as yearlySalary from s_emp;--可以
select last_name,salary*13 as 年薪 from s_emp;--可以
--查询员工的id , 并加10000显示, 给id添加别名 id heheda
select id+10000 "id heheda" from s_emp;
--查询员工的id , 并加10000显示, 给id添加别名 as不省略 id heheda
select id+10000 as "id heheda" from s_emp;
第二个字符是大写S的记录。
name like '_S%'
SELECT COLUMN1,COLUMN2
FROM TABLE1, TABLE2
WHERE CONDITIONS
GROUP BY COLUMN1,COLUMN2
ORDER BY COLUMN1,COLUMN2
默认升序:具体数值在排序时位于NULL 值之前。
select 字段1,字段2 from 表 group by 字段一;--错误 group by 要跟所有的非汇总函数字段
select 字段1,字段2 from 表 group by 字段一,字段2;
参考链接: https://blog.csdn.net/liuxiao723846/article/details/49020575
GROUP BY ROLLUP(ordered column list 0f grouping set)
1)对比没有带rollup的goup by :
Group by A,B产生的分组种数:1种;
group by A,B
返回结果集:也就是这一种分组的结果集。
2)带rollup但group by与rollup之间没有任何内容 :
A、Group by rollup(A ,B) 产生的分组种数:3种;
第一种:group by A,B
第二种:group by A
第三种:group by NULL
返回结果集:为以上三种分组统计结果集的并集且未去掉重复数据。
3)带rollup但groupby与rollup之间还包含有列信息
A、Group by A , rollup(A ,B) 产生的分组种数:3种;
第一种:group by A,A,B 等价于group by A,B
第二种:group by A,A 等价于group by A
第三种:group by A,NULL 等价于group by A
返回结果集:为以上三种分组统计结果集的并集且未去掉重复数据。
GROUP BY CUBE(column list of grouping sets)
1)假设有n个维度,rollup会有n个聚合:
rollup(a,b) 统计列包含:(a,b)、(a)、()
rollup(a,b,c)统计列包含:(a,b,c)、(a,b)、(a)、()
……以此类推ing……
2)假设有n个纬度,cube会有2的n次方个聚合:
cube(a,b) 统计列包含:(a,b)、(a)、(b)、()
cube(a,b,c) 统计列包含:(a,b,c)、(a,b)、(a,c)、(b,c)、(a)、(b)、(c)、()
SELECT COLUMN1,COLUMN2
FROM TABLE1, TABLE2
WHERE CONDITIONS
GROUP BY COLUMN1,COLUMN2
HAVING CONDITIONS
ORDER BY COLUMN1,COLUMN2
MySQL
select concat('A','B')
CONCAT(COLUMN_NAME ,[' ',] COLUMN_NAME [COLUMN_NAME])
Oracle
COLUMN_NAME || [''||] COLUMN_NAME [COLUMN_NAME]
TRANSLATE( CHARACTER SET , VALUE1 , VALUE2)
--所有的I都被替换为A 、N替换为B 、D 替换为C
SELECT TRANSLATE(CITY,'IND','ABC') FROM EMPLOYEE_TBL;
SELECT TABLE1.COLUMN1 , TABLE2.COLUMN2 ...
FROM TABLE1, TABLE2 [, TABLE3]
WHERE TABLE1.COLUMN_NAME = TABLE2.COLUMN_NAME
[AND TABLE1.COLUMN_NAME = TABLE3.COLUMN_NAME ]
SELECT EMPLOYEE_TBL.EMP_ID,
EMPLOYEE_PAY_TBL.DATE_HIRE
FROM EMPLOYEE_TBL,
EMPLOYEE_PAY_TBL
WHERE EMPLOYEE_TBL.EMP_ID=EMPLOYEE_PAY_TBL.EMP_ID;
SELECT E.EMP_ID, EP.SALARY, EP. DATE_HIRE, E.LAST_NAME
FROM EMPLOYEE_TBL E,
EMPLOYEE_PAY_TBL EP,
WHERE E.EMP_ID=EP.EMP_ID
AND EP.SALARY>20000;
SELECT TABLE1.COLUMN1 , TABLE2.COLUMN2 ...
FROM TABLE1, TABLE2 [, TABLE3]
WHERE TABLE1.COLUMN_NAME != TABLE2.COLUMN_NAME
[AND TABLE1.COLUMN_NAME!= TABLE3.COLUMN_NAME ]
具体范例如下:
SELECT EMPLOYEE_TBL.EMP_ID,
EMPLOYEE_PAY_TBL.DATE_HIRE
FROM EMPLOYEE_TBL,
EMPLOYEE_PAY_TBL
WHERE EMPLOYEE_TBL.EMP_ID != EMPLOYEE_PAY_TBL.EMP_ID;
salgrade : 工资级别表格
- grade工资级别 1-5
- losal这个级别最低工资
- hisal这个级别最高工资
1. between
select salary,last_name,grade from s_emp,salgrade where salary between losal and hisal;
2. and
select salary,last_name,grade from s_emp,salgrade where salary>=losal and salary<=hisal;
定义
分类:外连接被划分为左外连接、右外连接和全外连接。
语法:
外部结合的-般语法如下所示
FROM TABLEl
{RIGHT | LEFT | FULL} [OUTER] JOIN
ON TABLE2
Oracle 的语法是
FromSELECT A.COLUMN_NAME, B.COLUMN_NAME [, C.COLUMN_NAME]...
FAOM TABLE1 A, TABLE2 B [,TABLE3 C]
WHERE TABLE1A.COLUMN_NAME[(+)] = TABLE2 = B.COLUMN_NAME[(+)]
[ AND TABLE1A.COLUMN_NAME[(+)] = TABLE3.COLUMN_NAME[(+)] ]
把(+)加在where条件的字段后面,(+)号修饰的字段所在的表的对面表格的数据全部被选中 !
e.manager_id(+)=m.id: m表被全部选中 e.manager_id=m.id(+):e表被全部选中
特点: 内连接匹配不上的数据, 因为外连接要取出, 外连接会通过补足null行来生成结果集
查询s_emp表格, 获取普通员工的信息
select distinct m.last_name,m.id from s_emp e,s_emp m where e.manager_id(+)=m.id and e.manager_id is null;
e m
e.id e.name e.m_id m.id m.name m.m_id
1 a null 1 a null
2 b 1 2 b 1
3 c 1 3 c 1
4 d 2 4 d 2
5 e 2 5 e 2
select m.id,m.name from e,m where e.manager_id is null;
--查询测是的临时表
select * from s_emp_test;
--内连接 两张表的数据
select * from s_emp_test e1, s_emp_test e2
where e1.id=e2.m_id;
--内连接 一张表的数据 有重复
select e1.* from s_emp_test e1, s_emp_test e2
where e1.id=e2.m_id;
-- 外连接 (+)在=前 e2表中的数据全部展示出来,不符合条件的用NULL补充到e1
select * from s_emp_test e1, s_emp_test e2
where e1.m_id(+)=e2.id;
--外连接 (+)在=前 等同于如下右连接 e2为主表 e2表的数据全部展示,e1表用NULL补足
select * from s_emp_test e1 right join
s_emp_test e2 on e1.m_id=e2.id;
-- 外连接 (+)在=和字段后 e1表中的数据全部展示出来,不符合条件的用NULL补充到e2
select * from s_emp_test e1,
s_emp_test e2 where e1.m_id=e2.id(+);
--外连接 (+)在=和字段后 等同于如下左连接 e1为主表 e1表的数据全部展示,e2表用NULL补足
select * from s_emp_test e1 left join
s_emp_test e2 on e1.m_id=e2.id(+);
-- 查询普通员工 --
-- 左连接:查询普通员工(非领导的员工信息)根据上面的外连接(+)在后面,外连接补NULL,然后用e2表的ID is null 取出员工号
select * from s_emp_test e1, s_emp_test e2
where e1.id=e2.m_id(+) and e2.id is null;
-- 右连接:查询普通员工的另一种方式
select * from s_emp_test e1, s_emp_test e2
where e1.m_id(+)=e2.id and e1.id is null;
--注意用 where 而不是 and 用and去并集 不符合要求
select * from s_emp_test e1 right join
s_emp_test e2 on e1.m_id=e2.id where e1.id is null;
-- 查询领导 --
-- 右连接
select distinct e2.* from s_emp_test e1
right join s_emp_test e2
on e1.m_id = e2.id where e1.m_id is not null;
-- 左连接
select distinct e1.* from s_emp_test e2
left join s_emp_test e1 on e2.m_id = e1.id
where e2.m_id is not null;
--全外连接 左连接和有链接的结果取数学合集(去掉重复)
-- FULL JOIN 或 FULL OUTER JOIN
select * from s_emp_test e1 FULL JOIN s_emp_test e2 on e1.m_id=e2.id;
SELECT A.LAST_NAME, B.LAST_NAME , A.FIRST_NAME...
FROM EMPLOYEE_TBL A,
EMPLOYEE_TBL B
WHERE A.LAST_NAME = B.LAST_NAME;
SELECT COLUMN_NAME FROM TABLE
WHERE COLUMN_NAME = ( SELECT COLUMN_NAME FROM TABLE WHERE CONDITIONS);
1、select与子查询 常用
-- 查询低于编号311549902员工工资的 人员的的信息
select EP.PAY_RATE,E.EMP_ID,E.LAST_NAME,E.FIRST_NAME from EMPLOYEE_PAY_TBL EP,EMPLOYEE_TBL E where EP.SALARY >(SELECT SALARY from EMPLOYEE_PAY_TBL where EMP_ID='311549902');
2、子查询也可以用于DML(INSERT UPDATE DELETE等语句)不常用。