zoukankan      html  css  js  c++  java
  • SQL基础(一)

      经过这段时间对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的表:

    IdLastNameFirstNameAddressCity
    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('语文','数学','英语'));
  • 相关阅读:
    if——while表达式详解
    java算法:抽象数据类型ADT
    java算法:FIFO队列
    Android_NetworkInfo以及判断手机是否联网
    java算法:堆栈ADT及实例
    java算法:数据项
    java算法:一流的ADT
    java算法:复合数据结构
    java算法:字符串
    java算法:基于应用ADT例子
  • 原文地址:https://www.cnblogs.com/Jims2016/p/5678631.html
Copyright © 2011-2022 走看看