经过这段时间对SQL的基础学习,下面对自己的学习做个总结或者也可以说是个回顾吧!
我练习的是在oracle数据库平台上,并且安装了PLSQL Developer工具。下面是我从小白开始一路学习的回顾:
首先这是PLSQL Developer的登陆界面:
SQL SELECT 查询语法
基本查询:
SELECT 列名称 FROM 表名称
条件查询:
SELECT 列名称 FROM 表名称 WHERE 条件
条件排序查询:
SELECT 列名称 FROM 表名称 WHERE 条件 ORDER BY
INSERT INTO 插入语句
基本插入语句:
INSERT INTO 表名称 VALUES (值1, 值2, 值3,. . .)
指定所需要插入数据的列:
INSERT INTO 表名称(列1, 列2, 列3, . . . )VALUES (值1,值2,值3, . . .)
UPDATE 更新语句
基本更新语句:
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
更新某一行的若干列:
UPDATE 表名称 SET 列1 = 值1, 列2 = 值2, 列3 = 值3,. . . WHERE 条件
DELETE 删除语句
按条件删除:
DELETE FROM 表名称 WHERE 列名称 = 值
删除表的所有行:
DELETE FROM 表名称
或者:
DELETE * FROM 表名称;
默认情况下,我先是以管理员身份登陆,然后创建我自己练习的用户(jim)
那么是怎么来创建我的用户的呢?
CREATE USER 用户名 IDENTIFIED BY 密码
//创建新用户jim,密码就是changeit CREATE USER jim IDENTIFIED BY changeit
创建好的用户是什么功能都木有的,哪怕是登陆的权限也没有,这时候我们就要给新用户赋予一定的权限
给用户赋予登陆的权限:
/*给用户赋予登陆的权限*/ GRANT CONNECT TO jim;
这时候,用户jim是可以登录的,但是它还是没有权限去操作数据库,表这些对象,哪怕它自己建一个表的权利也没有,
这时候我们再给他赋一个对象的权限,这样他就可以创建表了:
/*给用户赋予创建表等对象的权限*/ GRANT RESOURCE TO jim;
这时候我们jim用户就有了基本的功能了,这时候我们在退出原来的用户,用jim用户即可登录。
这里顺平提下删除用户的方法:
/*那么对应得删除用户我们顺便提下*/ DROP USER jim
一般情况下,这样会报错不删除,出发jim用户是空的,什么表也没创建,
如果jim用户创建表,我们可以在后面加casecode,表示把jim用户下的所有资源全部删除
/*如果jim用户下有创建表,或者其他对象,这样是删除不了, 我们在后面加个casecode就可以*/ DROP USER jim CASECADE;
好了,赶紧用我们的新用户来登陆吧. . . .
我们先来创建一个叫作Persons的表:
Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Adams | John | Oxford Street | London |
2 | Bush | George | Fifth Avenue | New York |
3 | Carter | Thomas | Changan Street | Beijing |
对应的sql语句为:
/*创建Persons表*/ CREATE TABLE Persons( Id number, LastName nvarchar2(20), FirstName nvarchar2(20), Address nvarchar2(20), City nvarchar2(20));
这样一个空的表就创建成功了,但是里面的内容是空的,这时候我们可以往表中插入数据
完整的字段插入:INSET INTO 表名 VALUES(值1,值2,值3,. . .);
/*往Persons表插入数据*/ INSERT INTO Persons VALUES(1,'Adams','John','Oxford Street','London'); INSERT INTO Persons VALUES(2,'Bush','George','Fifth Avenue','New York'); INSERT INTO Persons VALUES(3,'Carter','Tomas','Changan Street','Beijing');
这样我们插入的是完整的数据,当然我们也可以插入部分字段的数据,
部分字段插入:INSERT INTO 表名(字段1,字段2,字段3. . .) VALUES (值1,值2,值3 . . . )
/*也可以给表中的部分字段添加数据*/ INSERT INTO Persons(Id,LastName,Firstname,City) VALUES(1,'Jiang','Jim','Dalian');
当然我们也可以修改表中的数据,比如我们修改FirstName为Jim的City为Wuyuan
UPDATE 表名 SET 字段1=新值 WHERE 字段1 = '某个值'
/*更新表中的数据*/ UPDATE Persons SET City = 'Wuyuan' WHERE FirstName = 'Jim';
再后来呢,我们可以删除我们不需要的数据,注意,删除数据需要特别小心
比如我们想删除某一行,一定要用WHERE加个限定,不然就真的是删除数据库跑路了.........
现在删除LastName = 'Jiang'这一行,我们可以这样写:
/*删除某一行数据*/ DELETE FROM Persons WHERE LastName = 'Jiang' ;
当然,你真的要删除所有,那就可以不用限定条件,直接把表中所有数据清空
/*清空数据*/ DELETE FROM Persons;
如果你要斩草除根,把数据连同表结构也一起删除,你可以这么干
/*章草除根,直接把表结构也删除的话就可以这么干*/ DROP TABLE Persons;
好了,三个单词一夜回到解放前,一无所有了 . . . .
In操作符
SELECT 字段名 FROM 表名称 WHERE 字段 IN (值1,值2,值3,值4, . . .)
BETWEEN. . .AND. . .区间语法
SELECT 字段名 FROM 表名称 WHERE 字段名 BETWEEN 值1 AND 值n
下面我们来创建一个时间维度表,假设表的名称为DIM_DATE
D_ID | D_DATE | D_YEAR | D_QUARTER | D_MONTH | D_WEEK |
20160723 | 2016/7/23 | 2016 | Q3 | JULE | SATURDAY |
--设计日期维度表 CREATE TABLE DIM_DATE( D_ID NUMBER(8) PRIMARY KEY, --20160723 D_DATE DATE, --2016/7/23 D_YEAR NUMBER, --2016 D_QUARTER CHAR(2), --Q3 D_MONTH NVARCHAR2(15), --JULE D_WEEK NVARCHAR2(15)); --SATURDAY
接下来我们可以往表中差数据,如果手工一条一条的插入数据,那将会要人命的,因此,我们可以写一个存储过程,可以从起始日期到结束日期
插入到数据表中,对对应的存储过程如下:
--创建存储过程,插入时间,从起止日期到结束日期 CREATE OR REPLACE PROCEDURE P_INSERTDATE(startDate NVARCHAR2,endDate nvarchar2) AS BEGIN MERGE INTO DIM_DATE t1 USING ( select to_number(to_char(to_date(startDate,'YYYY-MM-DD')+(rownum-1),'yyyymmdd')) t_date from dual connect by rownum<=(to_date(endDate,'YYYY-MM-DD')-to_date(startDate,'YYYY-MM-DD')) ) temp_date ON(t1.d_id=temp_date.t_date) when matched then update set t1.d_date=to_date(temp_date.t_date,'YYYY-MM-DD') ,t1.d_year=to_number(substr(to_char(temp_date.t_date),1,4)) ,t1.d_quarter='Q'||to_char(to_date(temp_date.t_date,'YYYY-MM-DD'),'Q') ,t1.d_month=to_char(to_date(temp_date.t_date,'YYYY-MM-DD'),'MONTH') ,t1.d_week=to_char(to_date(temp_date.t_date,'YYYY-MM-DD'),'DAY') when not matched then insert (t1.d_id,t1.d_date,t1.d_year,t1.d_quarter,t1.d_month,t1.d_week) values ( temp_date.t_date,to_date(temp_date.t_date,'YYYY-MM-DD'), to_number(substr(to_char(temp_date.t_date),1,4)), 'Q'||to_char(to_date(temp_date.t_date,'YYYY-MM-DD'),'Q'), to_char(to_date(temp_date.t_date,'YYYY-MM-DD'),'MONTH'), to_char(to_date(temp_date.t_date,'YYYY-MM-DD'),'DAY') ); END;
其中注意的几点,我们先要获取某段时间,这时候我们可以这么写,
比如获取从2016年7月23日至2017年7月22日这段日期:
SELECT to_date('2016-07-23','YYYY-MM-DD')+ROWNUM-1 FROM DUAL CONNECT BY ROWNUM <= to_date('2017-07-23','YYYY-MM-DD')-to_date('2016-07-23','YYYY-MM-DD');
结果:
在利用merge into即可在我们的时间维度表进行更新和插入。
1.用一条语句查出每门课都大于80分的学生姓名
NAME | SUBJECT | SCORE |
张三 | 语文 | 85 |
张三 | 数学 | 90 |
李四 | 语文 | 76 |
李四 | 数学 | 100 |
王五 | 语文 | 69 |
王五 | 数学 | 95 |
王五 | 英语 | 88 |
--创建学生成绩表 CREATE TABLE SCORES( NAME VARCHAR2(10), SUBJECT VARCHAR2(10), SCORE NUMBER); --插入数据 INSERT INTO SCORES VALUES('张三','语文',85); INSERT INTO SCORES VALUES('张三','数学',90); INSERT INTO SCORES VALUES('李四','语文',76); INSERT INTO SCORES VALUES('李四','数学',100); INSERT INTO SCORES VALUES('王五','语文',69); INSERT INTO SCORES VALUES('王五','数学',95); INSERT INTO SCORES VALUES('王五','英语',88);
思路:先对学生按姓名进行分组(group by),然后过滤(having)
--用一条语句查出每门课都大于80分的学生姓名 SELECT t1.name FROM SCORES t1 GROUP BY T1.NAME HAVING MIN(t1.score)>80;
也可以这么写,先把成绩低于80的学生姓名查找出来,然后再筛选(not in)
--查出每门课都大于80分的学生姓名(2) WITH temp AS (SELECT DISTINCT t1.name FROM SCORES t1 WHERE t1.score<80) --先找出成绩有低于80的学生姓名 SELECT DISTINCT t1.name FROM SCORES t1 WHERE t1.name NOT IN(SELECT * FROM TEMP);
2.对下表进行转换
NAME | SUBJECT | SCORE |
张三 | 语文 | 85 |
张三 | 数学 | 90 |
李四 | 语文 | 76 |
李四 | 数学 | 100 |
王五 | 语文 | 69 |
王五 | 数学 | 95 |
王五 | 英语 | 88 |
NAME | 语文 | 数学 | 英语 |
张三 | 85 | 90 | 0 |
李四 | 76 | 100 | 0 |
王五 | 69 | 95 | 88 |
SELECT t1.name ,sum(decode('语文',t1.subject,t1.score)) ,sum(decode('数学',t1.subject,t1.score)) ,sum(decode('英语',t1.subject,t1.score)) FROM SCORES t1 group by t1.name order by 1;
SELECT t1.name ,SUM(CASE WHEN t1.subject='语文' THEN t1.score ELSE 0 END) ,SUM(CASE WHEN t1.subject='数学' THEN t1.score ELSE 0 END) ,SUM(CASE WHEN t1.Subject='英语' THEN t1.score ELSE 0 END) FROM SCORES t1 group by t1.name;
--进行表的转换(pivot) SELECT * FROM ( SELECT t1.name ,t1.subject,t1.score from SCORES t1 group by t1.name,t1.subject,t1.score) PIVOT (SUM(score) FOR subject IN('语文','数学','英语'));