Oracle 原理:复杂的SQL语句
1.select [列名] from [表名] where [條件] group by [列名] having [條件] order by [列名]? 的執行順序。
?在查詢里面, 首先執行 from 來需要確定表,然后一條一條地遍歷表數據;執行where語句把符合的表數據行篩選數來,也就得到了可以輸出的數據;之后,將篩選出來的數據進行group by分組;之后用having來確定哪些數據不顯示;之后,用orderby來對顯示數據的數據進行排序。?
------------------------------------------------------分割線------------------------------------------------
有如下的? 工資表(雇員名稱,所屬部門,薪資,部門組長);
drop table salary_tbl; create table salary_tbl(employer_nm varchar(20),department varchar(20) not null,salary number not null,leader_nm varchar(20) ); truncate table salary_tbl; beginfor i in 1..100loopinsert into salary_tbl values('雇傭者'||i,'部門'||Mod(i,6),100*POWER(10000,i*0.01),'雇傭者'||Mod(i,6)); end loop; end; / commit;?
寫SQL一般先確定表和表之間的關聯關系,然后列出篩選條件個數,例如,查詢最高薪資的部門組長信息
①確認要查詢的表為 salary_tbl? ?② 篩選條件兩個:要為部門組長,在組長里薪資最高
------查詢薪資最高的部門組長----- select * from salary_tbl s where EMPLOYER_NM in (select distinct LEADER_NM from salary_tbl) --條件1:部門組長信息確定 and salary =(select max(salary) from salary_tbl s where --條件2: 薪資為部門組長里最高的 EMPLOYER_NM in (select distinct LEADER_NM from salary_tbl));對于復雜的增刪改語句中也是一樣的思路,首先確定表和表之間的關聯關系,確定要修改的字段,把篩選條件一一列舉出來就可以思路清晰地實現了
2.集合運算 union(并集),minus(差集),intersect(交集)
? Where 后面的條件篩選 也可以用集合運算來實現。
---------查詢薪資低于150塊錢部門組長信息(兩次)--------- select s.* from (select * from salary_tbl where EMPLOYER_NM=leader_nm) s minus select * from salary_tbl where salary>=150 --部門組長表和薪資大于150的差集 UNION ALL --不去重聯合查詢 select s3.* from (select s.* from (select * from salary_tbl where EMPLOYER_NM=leader_nm) s INTERSECT select * from salary_tbl where salary<150) s3; --部門組長表和薪資小于150的交集3.? rownum 和 Rowid
?rownum和rowid 在查詢時都不是直接展示的。其中rownum即行標,在執行完SQL查詢時后面添加上去的,所以每條數據的rownum根據不同的篩選條件是會變的,而rowId是由該數據行的物理地址信息所組成的字段。如果數據的物理位置沒變,那么rowid也就不會變,當查詢語句沒跟order by時,默認按rowId排序。如圖
當把rownum當做篩選條件時 只有 rownum < 或者 rownum <= 才能起效果,而大于,等于,不等于,between都不能有效的當做篩選條件。例如查詢該表中的最后5行數據
--------------- select * from (select salary_tbl.* ,rownum as row_num,rowID as row_id from salary_tbl) s where s.row_num between (select count(1) from salary_tbl )-5 and (select count(1) from salary_tbl); ---------------- select s.*,rownum from salary_tbl s minus select salary_tbl.*,rownum from salary_tbl where rownum< (select count(1) from salary_tbl )-5;4. case when..then....else? 和decode(value,if1,then1,if2,then2,if3,then3,...,else)
?case when...then ..else? 和decode 很像面向對象程序語言里的? if...elseif...elseif ..else 語句,但是decode里的 if條件只能用來判斷相等,而不能直接的進行比大小。
select s.employer_nm,s.department,case when s.salary<1000 then '窮鬼'when salary<8000 then '正常'when salary <40000 then '牛逼'else '大佬' end as 薪資水平,s.leader_nm from salary_tbl s ----------- select s.employer_nm,s.department,decode(sign(salary-10000),1,'高',-1,'低','剛好一萬元') as 薪資高低,s.leader_nm from salary_tbl s? 5. 變量,行變量,游標
例子:下面是輸出? ? 查詢表中的最后5行數據
declare max_num number;rowdata salary_tbl%rowtype; --行類型變量type cur_type is ref cursor; output1 cur_type ; --游標v_sql varchar2(2000) :=''; begin select count(1) into max_num from salary_tbl; -- 給變量賦值v_sql :='select s.employer_nm,s.department,s.salary,s.leader_nm from (select salary_tbl.*, rownum as row_num from salary_tbl) s where s.row_num between '|| (max_num-5)||' and '||max_num; --記得單詞間的空格,不用加分號open output1 for v_sql; LOOPfetch output1 into rowdata; exit when output1%notfound;dbms_output.put_line(rowdata.employer_nm || '|@|' ||rowdata.department || '|@|' ||rowdata.salary || '|@|' ||rowdata.leader_nm);END LOOP; --循環輸出end;輸出結果::
?
總結
以上是生活随笔為你收集整理的Oracle 原理:复杂的SQL语句的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ 正态分布、概率累积密度函数的使
- 下一篇: linux cmake编译源码,linu