天天看點

oracle查詢(select)

1.基本查詢

select xxx
from xxx
where xxx
group by xxx
having xxx
order by xxx
           

2.子查詢

select e.* 
from t_employee e
where e.employee_id in (select t.employee_id from t_salary t);
--使用exists替換上式中的in
select e.*
from t_employee e
where exists (select t.employee_id from t_salary s where t.employee_id=e.employee_id);
           

3.聯合語句

union 并集,剔除重複元素(相當于并集後執行了一次distinct)

union all 并集,包含重複元素(是以比union快)

intersect 交集

minus 差集(第一個查詢作為被減數,第二個查詢作為減數,差集的結果為第一個集合存在而第二個集合不存在的記錄)

4.連接配接

①自然連接配接:将兩個資料源中具有相同列的進行連接配接

select * from t_employee natural join t_manager;

②内連接配接

③外連接配接

左連接配接 left左邊的為主表,join右邊的為附表

select e.employee_id,e.employee_name,s.salary
from t_employee e left join t_salary s on e.employee_id=s.employee_id
order by e.employee_id;
--oracle寫法 e.employee_id=s.employee_id(+)帶加号的為附表,不帶的為主表
select e.employee_id,e.employee_name,s.salary
from t_employee e,t_salary s
where e.employee_id=s.employee_id(+)
order by e.employee_id;
--結果
EMPLOYEE_ID EMPLOYEE_NAME            SALARY
----------- -------------------- ----------
          1 金瑞                       8000
          1 金瑞                       8000
          1 金瑞                       8000
          2 鐘君                       7000
          2 鐘君                       7000
          2 鐘君                       7000
          3 王山                       7000
          3 王山                       7000
          3 王山                       7000
          4 劉迪                       7000
          4 劉迪                       7000
          4 劉迪                       7000
          5 鐘會                 
          6 張玉                 
          7 柳青                 
          8 胡東                 
          9 商乾                       4000
          9 商乾                       4000
          9 商乾                       4000
         10 王蒙                       5000
EMPLOYEE_ID EMPLOYEE_NAME            SALARY
----------- -------------------- ----------
         10 王蒙                       5000
         10 王蒙                       5000
           

右連接配接 left左邊的為附表,join右邊的為主表

select e.employee_id,e.employee_name,s.salary
from t_employee e right join t_salary s on e.employee_id=s.employee_id
order by e.employee_id;
--oracle寫法 e.employee_id(+)=s.employee_id帶加号的為附表,不帶的為主表
select e.employee_id,e.employee_name,s.salary
from t_employee e,t_salary s
where e.employee_id(+)=s.employee_id
order by e.employee_id;
--結果
EMPLOYEE_ID EMPLOYEE_NAME            SALARY
----------- -------------------- ----------
          1 金瑞                       8000
          1 金瑞                       8000
          1 金瑞                       8000
          2 鐘君                       7000
          2 鐘君                       7000
          2 鐘君                       7000
          3 王山                       7000
          3 王山                       7000
          3 王山                       7000
          4 劉迪                       7000
          4 劉迪                       7000
          4 劉迪                       7000
          9 商乾                       4000
          9 商乾                       4000
          9 商乾                       4000
         10 王蒙                       5000
         10 王蒙                       5000
         10 王蒙                       5000
18 rows selected
           

性能比較:二者的執行計劃和統計資訊一樣,看不出效率快慢,推薦使用left join可讀性高。

完全連接配接:左外連接配接和右外連接配接在一起

5.階層化查詢 connect by

--建立market表
create table market(
       market_id number,
       market_name varchar2(10),
       parent_market_id number
);

insert all
  into market values(1,'全球',0)
  into market values(2,'亞洲',1)
  into market values(3,'歐洲',1)
  into market values(4,'美洲',1)
  into market values(5,'中國',2)
  into market values(6,'南韓',2)
  into market values(7,'北韓',2)
  into market values(8,'英國',3)
  into market values(9,'德國',3)
  into market values(10,'法國',3)
  into market values(11,'美國',4)
  into market values(12,'墨西哥',4)
  into market values(13,'巴西',4)
  into market values(14,'北京',5)
  into market values(15,'天津',5)
  into market values(16,'上海',5)
select * from dual;  

select * from market;

--使用connect by進行階層化查詢market_id=14時,即北京的父節點
select * from market
start with market_id=14
connect by prior parent_market_id=market_id;
--結果
 MARKET_ID MARKET_NAME PARENT_MARKET_ID
---------- ----------- ----------------
        14 北京                       5
         5 中國                       2
         2 亞洲                       1
         1 全球                       0
--使用connect by 過濾出market_id=14且洲以下的父節點
select * from market
start with market_id=14
connect by market_id=prior parent_market_id and instr(market_name,'洲')=0;
--結果
 MARKET_ID MARKET_NAME PARENT_MARKET_ID
---------- ----------- ----------------
        14 北京                       5
         5 中國                       2
--connect by 使用場景
--建立market_customer表
create table market_customer(
       customer_id number,
       customer_name varchar2(50),
       customer_address varchar2(10),
       market_id number
);

--向market_customer表插入資料
insert all
  into market_customer values(1,'Air USA','Waston',11)
  into market_customer values(2,'飛盧财經','北京',5)
  into market_customer values(3,'曉金公司','北京',14)
  into market_customer values(4,'中國五金','天津',15)
  into market_customer values(5,'申業公司','上海',16)
select * from dual;
--使用connect by階層化查詢中國市場的market_customer資訊
--中國市場的子節點
select market_id from market
start with market_name='中國'
connect by prior market_id=parent_market_id;
--結果
 MARKET_ID
----------
         5
        14
        15
        16
--中國市場的子節點的客戶資訊
select * from market_customer
where market_id in(select market_id from market
start with market_name='中國'
connect by prior market_id=parent_market_id);
--結果
CUSTOMER_ID CUSTOMER_NAME                                      CUSTOMER_ADDRESS  MARKET_ID
----------- -------------------------------------------------- ---------------- ----------
          2 飛盧财經                                           北京                      5
          3 曉金公司                                           北京                     14
          4 中國五金                                           天津                     15
          5 申業公司                                           上海                     16
--sys_connect_by_path:将connect by查詢的結果集的每行記錄的列值用字元串串在一行表示,如:
select * from market
start with market_name='天津'
connect by prior parent_market_id=market_id;
-- 結果
MARKET_ID MARKET_NAME PARENT_MARKET_ID
---------- ----------- ----------------
        15 天津                       5
         5 中國                       2
         2 亞洲                       1
         1 全球                       0
select market_id,parent_market_id,sys_connect_by_path(market_name,'\')
from market
start with market_name='天津'
connect by prior parent_market_id=market_id;
--結果
 MARKET_ID PARENT_MARKET_ID SYS_CONNECT_BY_PATH(MARKET_NAM
---------- ---------------- --------------------------------------------------------------------------------
        15                5 \天津
         5                2 \天津\中國
         2                1 \天津\中國\亞洲
         1                0 \天津\中國\亞洲\全球
--隻擷取所有父節點的字元串
select max(max_path) from(
select market_id,parent_market_id,sys_connect_by_path(market_name,'\') max_path
from market
start with market_name='天津'
connect by prior parent_market_id=market_id);
--結果
\天津\中國\亞洲\全球
           

6.使用rownum進行分頁查詢

--使用rownum進行分頁查詢
select rn,student_id,student_name,student_age
from (select rownum rn,s.* from (select * from student order by student_name) s where rownum<=10)
where rn>5;
--結果集
        RN STUDENT_ID STUDENT_NAME STUDENT_AGE
---------- ---------- ------------ -----------
         6          4 趙六                  12
         7          6 周八                  14
         8          8 胥十                  12