1. 程式人生 > >Oracle學習筆記第7天

Oracle學習筆記第7天

Oracle學習筆記第7天

查詢這功能是經常使用的部分,可能我這邊暫時學到的只有這麼多,或許存在遺漏,如果有,以後補上。

先來個完整的,

SELECT [ALL|DISTINCT] TOP n [PERCENT] WITH THIS select_list
[INTO [new table name]]
[FROM {table_name | view_name}[(optimizer_hints)]
	[,{table_name2 | view_name2}[optimizer_hints]
    	[...,table_name16 | view_name16][
optimizer hints] ] ] [WHERE clause] [GROUP BY clause] [HAVING clause] [ORDER BY clause] [COMPUTE clause] [FOR BROWSE]
別看這這麼多,拆分介紹完,你就會發現,感覺還行,但是真正用的時候會很蛋疼。熟練就好了。
這玩意一次介紹說不清,分開介紹。
  1. 簡單查詢

    只有select 和 from 的查詢時簡單查詢。也是基本查詢,所有的查詢都必須包含這兩個子句。

    select * from teachers;		-- 查詢老師表裡所有的資料。
    
  2. 使用from子句指定表

    [FROM {table_name | view_name}[(optimizer_hints)]
    	[,{table_name2 | view_name2}[optimizer_hints]
        	[...,table_name16 | view_name16][optimizer hints]
    	]
    ]
    

    使用 from 可以查詢行和列所在的表,指定表後,就可以通過表查詢都所需要的行列值,注意這裡沒有where條件,所以查詢出來的資料是整張表的資料。

    table_name:表示表名,view_name:表示檢視名,檢視後面會介紹。

    在查詢其他角色對應的方案中的表時,需要指定該方案的名稱,即在表名前加對應的角色名,比如我的teachers表建在pptt角色下,則查詢為:

    select * from pptt.teachers;
    
  3. 使用select 指定列

    很多時候,我們查詢的可能只是某張表裡的某個或者某幾個欄位,並不需要查詢出整張表的資料。

    SELECT column_1 [name_1] [,... column_n name_n]
    FROM table_name_1 [tname_1] [, ... 	table_name_n,tname_n]
    
    column_1,column_n:要讀取的列名,可以為多個,也可以為一個。
       name_1:有的時候看列名很難理解其中的意思,可以在後面加一個字串代替這個列名,這個不會影響資料。
       table_name_1:要讀取的表名。
       [tname_1]:和name_1功能類似,不過是替換表名。當表名過長的時候,通過替換可以使得SQL變得簡潔。
    選擇列名的時候不用按照之前的順序,但是顯示的時候是按照你寫的列名順序排序的。
       在選擇列名的時候也可以對列名進行操作,包括一般的加(+)減(-)乘(*)除(/)
    
       select (degree + 5) '學生成績' from scores; -- 顯示每個學生加5分後的成績
    
  4. distinct / all關鍵字

    資料去重,比如說銀行的交易記錄,比如說你想從部門成員表中查詢有哪些部門,一個部門可能有多個人,這是這個部門在顯示的時候就是重複出現的,這時可以使用資料去重,使得相同的資料只存在一個。

    select distinct department_id from employees;
    

    all 則是查詢所有資料,一般忽略不寫。

  5. where 子句

    查詢的時候我們可能只需要符合某些條件的資料,而不是所有的資料,這時就可以使用where條件,篩選資料。

    1. 條件表示式

      可以使用類似 A = B,A < B,A != B,A<>B,A LIKE B,NOT<條件表示式>的語句。A、B可以是欄位,也可以是數字,也可以是字串。這裡條件比較的是你想要的資料符合哪些規則。

      like是匹配運算子,Oracle在匹配運算中支援萬用字元,“%”代表0個、1個或者多個任意字元,“_”代表一個任意字元。

      not 用於對裡面的結果取反。

      select * from teacher where tname like '李%'; -- 查詢所有的李老師。
      
    2. 連線運算子

      and、or

      當判斷條件不止一個時可以使用and、或者or連線多個條件,至於功能不在細說。

    3. null值

      null這玩意,我不怎麼喜歡,但是資料沒有的值的情況下,就是null值。

      判斷資料是否為null時特定判斷語法 is null 、 not is null;

      select * from students where sbrithday is not null; -- 查詢生日不為空的學生資訊
      
  6. order by 子句

    用於對查詢出來的資料進行排序。ASC是升序,DESC是倒序。

    select * from scores order by sno ASC,degree DESC; -- 查詢學生成績,按照課程升序後按照成績倒序。
    
  7. group by 子句

    按照查詢的資料進行分類。用於在查詢結果集中對記錄進行分組,以彙總資料或者為整個分組顯示單行的彙總資訊。

    比如說,我要查詢每個部分有多少人,這樣的話,我可以按照部分分組,然後統計每部門的人數。

    select count(1) from emp group by deptno;
    

    常用的統計函式

    函式 描述
    count 返回找到的記錄數
    min 返回一個數字列或是計算列的最小值
    max 返回一個數字列或是計算列的最大值
    sum 返回一個數字列或是計算列的總和
    avg 返回一個數字列或是計算列的平均值

    e.g 使用group by 子句對薪資記錄進行分組,統計薪資的平均值,總和,以及最大值。

    select job_id ,avg(salary),sum(salary),max(salary),count(job_id) from employees group by job_id;
    
    注意:在使用group by 語句的時候,需要滿足的條件:
    	1. 在 select 子句的後面只可以有兩類表示式,統計函式和進行分組的列名;
    	2. 在select 子句中的列名必須是進行分組的列,除此之外新增其他的列名都是錯誤的,但是, group by 子句後面的列名可以不出現在select子句中;
    	3. 如果使用了 where 子句,那麼所有參加分組計算的資料必須首先滿足 where 子句指定的條件;
    	4. 在預設情況下,將按照 group by 子句指定的分組列升序排列,如果需要重新排序,可以使用 order by 子句指定新的排序順序。
    
  8. Having 子句

    ​ having 與 where 的功能類似,但是 where 只能用於條件判斷,後面不能跟函式,having 後面可以供函式。

    ​ 在 select 語句中,首先由 from 子句找到資料表,where 子句則接收 from 子句的輸出的資料,而having 子句則接收來自 group by、where或者from子句的輸入。

    e.g:列出平均薪資大於10000的統計資訊

    select job_id,avg(salary),sum(salary),max(salary),count(*) 
    from  employees group by having avg(salary)>10000;
    
  9. 多表連線查詢

    1. 簡單連線

      連線查詢僅通過 select 子句和 from 子句來連線多個表,其查詢的結果是一個通過笛卡爾積所生成表。,就是由一個表的每一行與另一個表的每一行的資料連線在一起生成的表,查詢結果的行數是兩個表的行數的乘積。

      一般不用這樣的,資料冗餘,很多時候我們不需要這麼多資料,一般會加上條件限制。即加上 where 子句,只有當第一張表和第二張表符合 where 裡的條件時,才會顯示。

      有時候連線的表有相同的列,這時候就難以區分這列是哪個表的,這時候可以用表別名來區分。

      有的時候,表名過長,也可以使用表別名來時SQL簡潔。

      注意:使用表別名後,所有的欄位必須加上表別名,因為SQL解析器在解析 from 子句時會用表別名代替表名,如果沒有加表別名,或者還是用表名,則會報錯。

      e.g:查詢僱員資訊,以及僱員所對應的部分資訊,且只顯示工作部門為Shipping的僱員資訊

      select em.employee_id,em.last_name,dep.department_name
      from employees em,departments dep
      where em.department_id = dep.department_id
      and dep.department_name = 'Shipping';
      
    2. join連線

      from join_table1 join_type join_table2
      [on(join_condition)]
      
      join_table1,join_table2:要連線的表
      join_type:連線型別,常用有:內連線、自然連線、外連線和自連線。
      [on(join_condition)]:連線的條件。
      

      內連線:(關鍵字:inner join,inner 可以省略)

      內連線就是使用join指定用於連線的兩個表,使用ON指定連線表的連線條件,如果想進一步限制查詢範圍,則可以直接在後面新增where子句。

      e.g:使用內連線查詢僱員的資訊,名稱以及工作名稱。

      select em.employee_id,em.last_name,dep.department_name,j.job_title
      from employees em inner join jobs j
      on em.job_id = j.job_id
      inner join departments dep
      on em.department_id = dep.department_id
      where em.job_id = 'IT_PROG';
      

      自然連線:(關鍵字:natural join)

      在使用自然連線查詢多個表時,Oracle會將第一張表的列與第二張表中具有相同名稱的列進行連線,在自然連線中,使用者不需要明確指定進行連線的列,系統會自動完成。

      但是自然連線誒有一個限制,即連線的各個表之間必須具有相同名稱的列,這個在實際中可能和應用的實際含義發生矛盾。

      比如:僱員有家庭住址,,部門有所在地址,這兩個連線就會放在一起,這樣的連線時毫無意義的。所以自然連線一般使用的很少。

      外連線:

      外連線分為三種:左外連線(left outer join 或者 left join)、右外連線(right outer join 或者 right join)、全外連線(full outer join 或者 full join)

      外連線與內連線的區別:外連線不只列出連線條件匹配的行,還列出左表(左外連線時)、右表(右外連線時)或者兩個表(全外連線時)中所有符合搜尋條件的資料行。

      理解很簡單,就比如說現在有兩個集合,內連線就是找出兩個集合的交集,左外連線就是找出左邊集合的全部,同時左邊集合與右邊集合的交集部分會附帶右邊集合的資料,右外連線同理,全外連線就是左右兩個集合的並集,左外連線和右外連線的交集部分會按照條件聚集在一起。

      自連線:

      自連線就是自己再次連線自己。

  10. 集合操作

    集合操作就是講兩個或者多個SQL查詢結果合併構成複合查詢,以完成一些特殊的任務需求,集合操作主要有集合操作符實現,常用的集合操作符包括:

    UNION(並運算)、UNION ALL、INTESECT(交運算)和MINUS(差運算)。

    1. UNION

      UNION 運算子可以將多個查詢結果集相加,形成一個結果集,其結果等同於集合運算中的交運算,並消除其中重複的行形成一個合集。

      e.g:查詢以 C 或者以 S 開頭的僱員,UNION 上 以 S 開頭或者以 T 開頭的僱員,這時返回的結果集有以C、S、T 開頭的僱員。

      select employee_id,last_name
      from employees
      where last_name like 'C%' or last_name like 'S%'
      union
      select employee_id,last_name
      from employees
      where last_name like 'S%' or last_name like 'T%'
      
    2. UNION ALL

      這個和 UNION 功能一致,但是這個不會去除重複行。

    3. INTERSECT

      INTERSECT操作符也用於對兩個SQL語句所產生的結果集進行處理,不同之處是 UNION 基本上是一個 OR 運算,而 INTERSECT 則比較像 AND。即UNION 交集運算,而 INTERSECT 是並集運算。

      e.g:查詢以 C 或者以 S 開頭的僱員,INTERSECT上 以 S 開頭或者以 T 開頭的僱員,這時返回的結果集只有 S 開頭的僱員。

      select employee_id,last_name
      from employees
      where last_name like 'C%' or last_name like 'S%'
      INTERSECT
      select employee_id,last_name
      from employees
      where last_name like 'S%' or last_name like 'T%'
      
    4. MINUS

      MINUS 集合運算可以找到兩個給定的集合之間的差集,返回的是第一個查詢中有的,但是第二個查詢中沒有的。

      e.g:查詢以 C 或者以 S 開頭的僱員,MINUS上 以 S 開頭或者以 T 開頭的僱員,這時返回的結果集只有 C 開頭的僱員。

      select employee_id,last_name
      from employees
      where last_name like 'C%' or last_name like 'S%'
      MINUS
      select employee_id,last_name
      from employees
      where last_name like 'S%' or last_name like 'T%'
      
    使用集合操作符的規則:
    	1. 在構成符合查詢的各個查詢中,各 select 語句指定的列必須在數量上和資料型別上相匹配;
    	2. 不允許在構成複合查詢的各個查詢中規定 order by 子句;
    	3. 不允許在BLOB、LONG 這樣的大資料型別物件上使用集合操作符。
    
  11. 子查詢

    子查詢是一個 select 語句,它可以在 select 、insert 、 update 或者 delete 語句中使用。

    1. IN 關鍵字

      使用IN 關鍵字可以將原表中特定列的值域子查詢返回的結果集中的值進行比較,如果某行的特定列的值存在,則在select語句的查詢結果中就包含這一行。

      e.g:查詢所有部門在某一地區(1700)的僱員資訊。

      select employee_id,last_name,department_id
      from employees
      where department_id in (select department_id
      						from departments
                              where location_id = 1700);
      
    2. EXISTS 關鍵字

      EXISTS關鍵字只注重子查詢是否返回行,如果子查詢返回一個或多個行,那麼 EXISTS 便返回 true,否則 false。

      由於 EXISTS 關鍵字的返回值取決於查詢是否會返回行,而不取決於這些行的內容,因此對子查詢來說,輸出的列表無所謂,可以使用 * 代替。

    3. 比較運算子

      包括:=、<>(不等於)、<、>、<=、>=。