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;
begin
for i in 1..100
loop
insert 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;
LOOP
fetch output1 into rowdata;
exit when output1%notfound;
dbms_output.put_line(rowdata.employer_nm || '|@|' ||
rowdata.department || '|@|' ||
rowdata.salary || '|@|' ||
rowdata.leader_nm);
END LOOP; --循環輸出
end;
輸出結果::