數據庫從入門到刪庫跑路(一) - -SQL語句

數據庫技術(1)-SQL語句

(1)基本SQL語句
SQL語句分爲一下三種類型:

  • DML:Data Manipulation Language:數據操縱語言
    • 用於查詢與修改數據記錄
      • INSERT
      • UPDATE
      • DELETE
      • SELECT
  • DDL:Data Definition Language 數據定義語言
    • 用於定義數據庫的結構,比如創建,修改,或刪除對象
      • CREATE TABLE
      • ALTER TABLE
      • DROP TABLE
      • CREATE INDEX
      • DROP INDEX
  • DCL:Data Control Language 數據控制語言
    • 用來控制數據庫的訪問

基本SQL語句

  • 查詢表中所有列
    select * from employee;
  • 查詢表中的特定列
     select employee_id,lat_name,email from employees;
- 注:sql對大小寫不敏感
- 日期可以進行加減,但是不可以進行乘除運算
- 空值是無效的,未指定的,未知或不可預知的值
- 空值不是空格或者0
- 包含空值的數學表達式的值都爲空值
- 連接符
    - 把列與列,列與字符連接起來
    - 用 '||'表示,相當於連接符號+s
        - 可以用來合成列
        - eg.
            - select  last_name ||' `s job_id is '|job_id
  • 查看錶結構
  • desc [table_name]<=======sql plus的關鍵字
  • 更改列名
    - select employee_id id,last_name name,12*salary annual_sal from [table_name]
    - select employee_id as id .... as可加可不加 
    - select employee_id as "id",last_name "Name",12*salary annual_sal from employee (當需要確定大小寫時一定需要加上引號)
  • 去除重複行
   - select distinct department_id from employees;
  • sql語句
    • 一種語言
    • ANSI標準
    • 關鍵字不能縮寫
  • sql*plus命令
    • 一種環境
    • Oracle的特性之一
    • 關鍵詞以縮寫
    • 命令不能改變數據庫中數據的值
    • 集中運行

(2) 過濾和排序數據

  - 過濾
  
     - eg1.
       - select last_name,hire_date from employees where to_char(hire_datem'yyyy-mm-dd')='1994-06-07'
     - 過濾條件
        - between and(適合連續值):包含邊界
        - in(適合離散值)
           - select last_name,department_id,salary from employees
             where department_id in(70,80,90)
        - like查詢
           - eg.員工中含有字符a的員工有哪些
               - select last_name,department_id,salary from employees where last_name like '%a%'
               - % 表示從0-無窮多個
           - eg.員工中名字的第二位是a的員工有哪些
               -  select last_name,department_id,salary from employees where last_name like '_a%'
           -  eg.員工中名字的第三位是a的員工有哪些
               -  select last_name,department_id,salary from employees where last_name like '__a%'
           - eg.查詢員工中的名字含有下劃線的人有哪些
               - 假設有個員工爲'wgha_lanan'
               - select last_name like '%#_%' escape '#'
               - select last_name like '%\_%' escape '\'
        - is null  與 is not null
   - 排序 Order by
     - select last_name,department_id,salary from employees
       where department_id=80
       order by salary asc(升序)
    - select last_name,department_id,salary from employees
       where department_id=80
       order by salary asc,last_name asc

(3) 單行函數(dual對應一個虛表)

  • 定義:
    • 一行記錄對應好一個結果
      • 字符函數
        • 大小寫控制
          • lower(‘ADFAD’) 小寫
          • upper('ADAjj) 大寫
          • initcap(‘sdsSDS’) 首字母大寫
        • 字符控制函數:
          • CONCAT 連接
          • SUBSTR 取子串(下角標從1開始)
          • LENGTH
          • INSTR
          • LPAD:左對齊:LPAD(SALARY,10,’’):左邊填不滿用補齊
          • RPAD:右對齊
          • TRIM:將一個字符從一個字符串去除,只可以去除首和尾
          • REPLACE
      • 數字函數
        • ROUND:四捨五入函數
        • TRUNC:截斷函數
        • MOD():取餘函數
      • 日期函數
        • 可以用數字除以24來向日期加上或減去天數
        • MONTHS_BETWEEN:兩個日期相差的月數
        • ADD_MONTHS:向制定日期中加上若干月數
        • NEXT_DAY:指定日期的下一個星期’對應的日期’
        • LAST_DAY:本月的最後一天
        • ROUND:日期四捨五入
        • TRUNC:日期截斷
      • 轉換函數
        • 數據類型轉換
          • 隱式
            • date<---->varchar2<----->number
          • 顯示
            • 字符與日期(char–date):
              • where hire_date=‘7-6月-94’
              • where to_char(‘hire_date’,‘yyyy-mm-dd’)=‘1997-06-07’
              • where to_date(‘1997-06-07’,‘yyyy-mm-dd’)=hire_date
            • 字符與數字
              • to_number
              • to_char
      • 通用函數
        • NVL:將空值轉換成一個已知的值
        • NVL2(expr1,expr2,expr3)
        • NULLIF(expr1,expr2):相等返回NULL,不等返回expr1
    • 條件表達式
      • case表達式
           select last_name "last_name",job_id "job_id" when 'AD_PERS' then 'A'
                                                         when 'ST_MAN'  then 'B'
                                                         when 'IT_PROG' then 'C'
                                                         when 'SA_REP'  then 'D'
                                                         when 'ST_CLERK' then 'E' end "Grade"
          from employees
     - decode表達式
            select last_name,job_id,decode(job_id,'AD_PERS','A',
                                                   'ST_MAN','B',
                                                   'IT_PROG','C',
                                                   'SA_REP','D',
                                                   'ST_CLERK','E') "Grade"
            from employees

(4)多表查詢

  • 等值連接
查詢出公司員工的last_name,department_name,city:
  select last_name,department_name,city
  from department d,employees e,location l
  where d.department_id=e.department_id and d.location_id=l.location_id;


查詢出last_name 爲'Chen'的manager的信息 (員工的employee_id等於員工的manager_id)

0) 例如:老張的員工號爲:"1001",我的員工號爲:"1002"
   我的manager_id爲 "1001"-----我的manager是"老張"
1) 通過兩條sql語句進行查詢

   select manager_id
   from employees
   where lower(last_name)='chen' --- 返回的結果爲108

   select *
   from employees
   where employee_id=108
2) 同過一條sql查詢(自連接)
   select m.*
   from employees e,employees m
   where e.manager_id=m.employee_id and e.last_name='Chen'
3) 通過一條sql查詢(子查詢)
    select * 
    from employees
    where employee_id=(
        select manager_id
        from employees
        where last_name='Chen'
    )

  • 非等值連接
查詢每個員工的last_name 和 GRADE_LEVEL (在JOB_GRADES 表中)-----非等值連接
  select last_name,GRADE_LEVEL
  from employees e,job_grades j
  where e.salary>=j.lowest_sal and  e.salary<=j.hightest_sal
  • 外連接
    • 左外連接
   select last_name,e.department_id,department_name
   from employee e,department d
   where e.department_id=d.department_id(+)

  • 右外連接
      select last_name.e.department_id,department_name
      from employee e,department d
      where e.department(+)=d.departemnt_id

理解(+)的位置: 以左外連爲例,因爲在左表需要返回更多的記錄,右表就需要加上更多的
記錄,因此在右表的鏈接條件上加上"(+)"

  • sql 99 的左外連接,右外連接,滿外連接
1) 左外連接
    select last_name,department_name
    from employees e left join departments d
    on e.department_id=d.department_id
2) 右外連接
    select last_name,department_name
    from employees e right join in departments d
    on e.departemnt_id=d.department_id
3) 滿外連接
    select last_name,departemnt_name
    from employees e full join in departemnnts d
    on e.departemnt_id=d.departemnt_id

  • sql 99 中連接 Employees 和 Departement表
1) 缺點:要求兩個表中的必須擁有一樣會的別名
   select * 
   from employees join departments
   using(department_id)
2) 
   select *
   from employees e join departments d
   on e.department_id=d.department_id
3) 多表連接
   select e.last_name,d.departemnt_name,l.city
   from employees e join departments 
   on e.department_id=d.department_id
   join locations l
   on d.location_id=l.location_id   
      

(5) 分組函數

  • 分組函數作用於一組數據,並對一組數據返回一個值

  • 不能在WHERE子句中使用組函數

  • 可以在HAVING子句中使用組函數

  • 組函數類型

    • AVG
      • 只能存放number類型
    • COUNT
      • 返回記錄中的總數
      • 只記錄非空記錄
      • AVG實際是由SUM/COUNT 而來,因此其計算時也忽略的空值
      • 可使用NVL函數使分組函數無法忽略空值
    • MAX
    • MIN
    • STDDEV
    • SUM
      • 只能存放number類型
組函數應用:
  select AVG(SALARY) MAX(SALARY) MIN(SALARY) SUM(SALARY)
  from employees;

NVL函數使分組隱函數無法忽略空值:
  select AVG(NVL(commission_pot,0))
  from employees;

COUNT(DISTINCE expr) 返回expr非空且不重複的記錄總數
  select COUNT(DISTINCT department_id)
  from employees;
求出EMPLOYEES表中各部門的平均工資(按照不同部門進行分組)
   select department_id,AVG(salary)
   from employees
   where department_id in(40,60,80)
   group by department_id


在SELECT 列表中所有未包含在組函數中的列都應該包含在GROUP BY子句中

HAVING:
  select department_id,avg(salary)
  from employees
  having avg(salary)>6000
  group by department_id
  order by department_id asc  
嵌套組函數
  select max(avg(salary))
  from employees
查詢公司在1995-1998之間,每年僱傭的人數的格式
select count(*) "total"
       count(decode(to_char(hire_date,'yyyy').'1995',1,null)) "1995"
       count(decode(to_char(hire_date,'yyyy').'1996',1,null)) "1996" count(decode(to_char(hire_date,'yyyy').'1997',1,null)) "1997" count(decode(to_char(hire_date,'yyyy').'1998',1,null)) "1998"
from employees
where to_char(hire_date,'yyyy') in (1995,1996,1997,1998)

(6) 子查詢

  • 單行子查詢
  • 多行子查詢
    • IN: 等於列表中的任意一個
    • ANY: 和子查詢返回的某一個值進行比較
    • ALL: 和子查詢返回的所有值進行比較
--- 誰的工資比Abel高?
select last_name,salary
from employees
where salary>( select salary
               from employees
               where last_name='Abel')
--- 查詢員工名爲Chen的manager的信息
  select last_name,salary 
  from employees
  where employee_id=( select manager_id
                      from employees
                      where last_name='Chen')
--- 查詢平均工資最高的job信息


7.創建和管理表(DDL)

  • 常見的數據庫對象:
    - 表:基本的數據存儲集合,由行和列組成
    - 視圖:從表中抽出的邏輯上相關的數據集合
    - 序列: 提供有規律的數值
    - 索引: 提高查詢的效率
    - 同義詞: 給對象起別名

  • 表名和列名:

    • 必須以字母開頭
    • 必須在1-30個字符之間
    • 必須只能包含A-Z,a-z,0-9,_,$,和#
    • 必須不能和用戶定義的其他對象重名
    • 必須不能是Oracle的保留字
  • 數據類型:

    • VARCHAR2(size) 可變長字符數據
    • CHAR(size) 定長字符數據
    • NUMBER(p,s) 可變長數值數據
    • DATE:日期型數據
    • LONG:可變長字符數據,最大可達到2G
    • CLOB:字符數據,最大可達到4G
    • RAW(LONG RAW):原始的二進制數據
    • BLOB:二進制數據,最大可達到4G
    • BFILE: 存儲外部文件的二進制數據最大可達到4G
    • ROWID: 行地址
    • 語句(以下DDL命令,操作之後皆不可回滾)
      • 創建表: create table
      • 修改表結構: alter table
      • 刪除表: drop table
      • 重命名錶: rename to
      • 刪除表中的所有數據,並釋放存儲空間: truncate table
Oracle數據庫中的表:

1.查看用戶創建的表:
   select * from user_tables;

2.創建表的第一種方式(白手起家):
create table emp1(
  id number(10),
  name varchar2(20),
  salary number(10,2),  //整個10位,小數位2位
  hire_date date
)
3.顯示錶結構
desc emp1

4.創建表的第二種方式(依託於現有的表):
create table emp2
as
select employee_id id,last_name name,hire_date,salary
from employees

5. 修改表*(修改數據類型必須是空表):
alter table emp1
add(email varchar2(20))

alter table emp1
modify(id number(15))

6.刪除表
drop tabel emp5;

7.清空表(只是清除表中的數據)
truncate table emp3(不能回滾)

8.改名
rename emp2 to employees2;

8.數據處理

創建空表
create table emp1
as 
select employee_id,last_name,hire_date,salary from employees
where 1=2  

插入一條數據(數據格式一一對應)
insert into emp1
values(1001,'AA',sysdate,10000)

insert into emp1
values(1002,'BB',tochar('1998-12-21','yyyy-mm-dd'),20000)

insert into emp1
values(1003,'CC',to_date('1999-12-21','yyyy-mm-dd'),null)


插入不足值的數據 要求類型與數據一一對應
insert into emp1(employee_id,last_name,hire_date)
values(1004,'DD',to_date('1999-12-21','yyyy-mm-dd'))


從其他表中拷貝數據:
insert into emp1(employee_id,hire_date,last_name,salary)
select employee_id,hire_date,last_name,salary
from employees

創建腳本:
insert into emp1(employee_id,,last_name,salry,hire_date)
values(&id,'&name',&salary,'&hire_date')

更改數據 UPDATE

update emp1
set salary=12000
where employee_id=179
提交
commit; 

刪除數據:DELETE語句

從employees1表中刪除dept1部門名稱中含pubic字符的部門id
delete from employees1
where department_id=(

          select department_id
          from depaetments
          where department_name like='Public'
)

  • 數據庫事務
    • 事務:一組邏輯操作單元,使數據從一種狀態變換到另一種狀態
    • commit:提交相當於保存
    • rollback:
      • savepoint A;
      • rollback to savepoint A;
    • 提交或回滾前的操作
      • 其他用戶不能看到用戶所做的改變,直到當前用戶結束事務
      • DML語句所涉及到的行被鎖定,其他用戶不能操作
    • 提交後的數據狀態
      • 鎖被釋放,其他用戶可以操作涉及到的數據
  • sql優化

9.約束

  • 什麼是約束:
    • 約束是表級的強制規定
  • 常見的約束:
    • NOT NULL
    • UNIQUE
    • PRIMARY KEY:主鍵
      • 不能加上空值
      • 主鍵唯一
    • FOREIGN KEY:外鍵
    • CHECK
  • 創建和修改約束
    • 建表的同時
    • 建表之後
  • 表級約束和列級約束
    • 列級約束只能作用在一個列上
    • 表級約束:可以作用在多個列上
  • 添加約束的語法:
    • 添加或刪除約束,但不能修改約束
    • 有效化或無效化約束
    • 添加 NOT NULL 約束要使用 modify語句
創建表:
create table emp2(
    id number(10) contraint emp2_id_nn  not null,  // 顯示聲明約束
    name varchar2(20) not null,
    salary(10,2)
)
顯示錶:
desc emp2


創建表
create table emp3(
---列級約束
  id number(10) contraint_emp3_id_uk unique,
  name varchar2(20) contraint emp3_name_nn not null,
  email varchar(20),
  salary number(10,2),
---表級約束
  contraint emp3_email_uk unqiue(email)
)

創建表
create table emp4(
---列級約束
  id number(10) contraint_emp4_id_pk primary key,
  name varchar2(20) contraint emp4_name_nn not null,
  email varchar(20),
  salary number(10,2),
---表級約束
  contraint emp3_email_uk unqiue(email)
  contraint emp6_id_fk foreign key(department_id) references departments(department_id)
)

10.視圖:view

  • 視圖
    • 視圖是一種虛表
    • 視圖建立在已有表的基礎上,視圖賴以建立的這些表稱爲基表
  • 爲什麼要使用視圖:
    • 控制數據訪問
    • 簡化查詢
    • 避免重複訪問相同的數據
  • 簡單視圖和複雜視圖
    • 沒使用分組函數的爲簡單視圖
    • 使用分組函數的爲簡單的視圖
  • Top-N 分析:
    • 傳最大的幾個值的Top-N分析
    • 對ROW_NUM只能使用小於等於
    • row_num:表示僞列,數據本身沒有這樣的列,是Oracle數據庫爲每個數據表加上的列可以標識行號,默認情況下,rownum按主索引進行排序,沒有則自然排序
1.創建視圖
create view empview
as
select employee_id,last_name,salary
from employees
where department_id=80
2.視圖修改
3.視圖中刪除
delete from empview
where employee_id=176
4.基於多個表創建視圖
create view empview2
as 
select employee_id,id,last_name,name,department_name
from employee e,department d
where e.department_id=d.department_id
5.修改視圖
使用 create or replace view子句修改視圖
6.屏蔽DML操作,可以使用with read only 選項屏蔽對視圖的DML的操作
with read only
7.刪除視圖
drop view [view_names];
8.top-n分析:

查詢工資排名前10的工資:
select rownum,employee_id,last_name,salary
from(
    select rownum,employee_id,last_name,salary
    from employees
    order by salary desc
)
where rownum<=10

查詢40-50
select rn,employee_id,last_name,salary
from(
    select rownum rn,employee_id,last_name,salary
    from(
        select employee_id,last_name,salary
        from employees
        order by salary desc
    )
)
where rn>40 and rn<=50

9.對Orac對象le進行分列
select employee_id,last_name,salary
from(
    select rownum rn,employee_id,last_name,salary
    from employees
) e
where e.rn<=pageNo*pageSize and e.rn>(pageNo-1)*pageSize

11.其他數據庫對象

  • 序列

    • 可以多個用戶來產生唯一數值的數據庫對象
    • 自動提供唯一的數值
    • 共享對象
    • 主要用於提供主鍵值
    • 將序列值裝入內存中可以提高訪問效率
  • 修改序列的注意事項:

    • 必須是序列的擁有者,或者對序列有ALTER權限
    • 只有將來的序列值會被改變
    • 改變序列的初始值只能通過刪除序列之後重建序列的方法實現
  • 使用序列:會出現"裂縫"現象

  • 索引

    • 一種獨立於表中的模式對象,可以存儲在與表不同的磁盤或表空間中
  • 創建索引

    • 自動索引
    • 手動創建索引
  • 什麼時候創建索引

    • 列中數據值分佈範圍很廣
  • 什麼時候不要創建索引:

    • 表很小
  • 同義詞

1.創建一個序列:
create sequence empseq
increment by 10  --每次增長10
start with 10    --從10開始增長
maxvalue 100     --提供的最大值
cycle            --需要循環
nocache          --不需要緩存
2.// 首次必須先進行nextval
select empseq.curval from dual
select empseq.nextval from dual
// 序列的使用
create table emp01
as
select employee_id,last_name,salary
from employees
where 1=2
3.// 修改序列
alter sequence empseq
increment by 12
nocycle
4.創建索引
create index emp01_id_ix
on emp01(employee_id)
5.刪除索引

6.創建同義詞
CREATE SYNONYM e FOR employees

12.控制用戶權限

數據庫安全性:
- 系統安全性
- 數據安全性
系統權限:對於數據庫的權限
- 有一百多種權限
- 數據庫管理員具有高級權限以完成管理任務
對象權限:操作數據庫對象的權限

1.創建用戶
create user xiaoyao
identified by xiaoyao
2.用戶的系統權限-創建會話
grant create session
to xiaoyao

grant create table
to xiaoyao
3.創建用戶表空間
alter user xioayao quota unlimted(5m)
on users;
4.更改用戶賬戶密碼
alter user xiaoyao
identified by xiaoyaotest
5.創建角色
create role my_role;
6.賦予角色權限
grant create session,create_tabe,create view to my_role

create user xiaoyao02
grant my_role to xiaoyao02
7.對象權限
grant select,update
on scott.employees
to xiaoyao
8.with grant options:表示可以可別人授予權限
  public 關鍵字:表示給所有用戶權限  
9.revoke 語句表示收回已授予的權限

13.SET操作符

  • UNION/UNION ALL: 求並集
    • 默認按照第一列順序排序
  • INTERSECT: 求交集
  • MINUS: 求差集
列數必須對應相同 實現兩個表的並集
select emplyee_id,department_id
from employees01
union all
select employee_id,department_id
from employee02

14.高級子查詢

1.多列子查詢

開始實現:
select employee_id,manager_id,department_id
from employees e1
where manager_id in (
    select manager_id
    from employees
    where employee_id in (141,174)
) and department_id in (
   select department_id
   from employees
   where employee_id in (141,174)
)
and empoyee_id not in(141,174)

多列子查詢:
 select employee_id,manager_id,department_id
 from employees e1
 where (manager_id,department_id) in (
     select (manager_id,department_id)
     from employees
     where employee_id in (141,174)
 )
 and employee_id not in (141,174)

2.在FROM 子句中使用子查詢

select last_name,department_id,salary
from employees e1
where salary> (
   select avg(salary)
   from employees e2
   where e1.department_id=e2.department_id
   group department_id
)
3. 相關子查詢:按照一行接一行的順序只能執行,主查詢的每一行都執行一次子查詢
select last_name,salary,department_id
from employees outer
where salary>(
    select avg(salary)
    from employees
    where department_id=outer.department_id
)
4.EXISTS 操作符
 - 檢查在子查詢中是否存在滿足條件的行
5. NOT EXISTS 操作符
6.with子句

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章