Oracle05、函數+多表查詢+子查詢+集合查詢+分頁+創建表約束

来源:http://www.cnblogs.com/Java766357768/archive/2017/10/13/7663011.html
-Advertisement-
Play Games

一、通用函數和條件判斷語句 單引號出現的地方如下:1)字元串,例如:'hello'2)日期型,例如:'17-12月-80'3)to_char/to_date(日期,'YYYY-MM-DD HH24:MI:SS')雙引號出現的地方如下:1)列別名,例如:select ename "姓 名" from ...


一、通用函數和條件判斷語句

/*使用NULLIF(a,b)通用函數,在類型一致的情況下,如果a與b相同,返回NULL,否則返回a,比較10和10.0是否相同*/
select NULLIF(10,10.0) from dual;

/*使用SQL99標準通用語法中的case表達式,將職位是分析員的,工資+1000;職位是經理的,工資+800;職位是其它的,工資+400
case 欄位 
     when 條件1 then 表達式1
     when 條件2 then 表達式2
     else 表達式n
end 
課後請參考<MySQL5.X的手冊>-12.2這個章節*/
select ename "姓名",
       job "職位",
       sal "漲前工資",
       case job
         when 'ANALYST' then
          sal + 1000
         when 'MANAGER' then
          sal + 800
         else
          sal + 400
       end "漲後工資"
  from emp;

/*使用oracle專用語法中的decode()函數,職位是分析員的,工資+1000;職位是經理的,工資+800;職位是其它的,工資+400
decode(欄位,條件1,表達式1,條件2,表達式2,...表達式n)*/
select ename "姓名",
       job "職位",
       sal "漲前工資",
       decode(job, 'ANALYST', sal + 1000, 'MANAGER', sal + 800, sal + 400) "漲後工資"
  from emp;

單引號出現的地方如下:
1)字元串,例如:'hello'
2)日期型,例如:'17-12月-80'
3)to_char/to_date(日期,'YYYY-MM-DD HH24:MI:SS')

雙引號出現的地方如下:
1)列別名,例如:select ename "姓 名" from emp
2)to_char/to_date(日期,'YYYY"年"MM"月"DD"日" HH24:MI:SS')單引號中的英文字元大小寫不敏感

二、多行函數

函數:oracle伺服器先事寫好的一段具有一定功能的程式片段,內置於oracle伺服器,供用戶調用。
單行函數:輸入一個參數,輸出一個結果,例如:upper('baidu.com')->BAIDU.COM
多行函數:輸入多個參數,或者是內部掃描多次,輸出一個結果,例如:count(*)->14

/*統計emp表中員工總人數*/
select count(*) from emp;
*號適用於表欄位較少的情況下,如果欄位較多,掃描多間多,效率低,項目中提倡使用某一個非null唯一的欄位,通常是主鍵 

/*統計公司有多少個不重覆的部門*/
select count(distinct deptno) from emp;

/*統計有佣金的員工人數*/
select count(comm) from emp;
註意:今天這些多行函數,不統計NULL值

/*員工總工資,平均工資,四捨五入,保留小數點後0位*/
select sum(sal) "總工資", round(avg(sal), 0) "平均工資" from emp;

/*查詢員工表中最高工資,最低工資*/
select max(sal) "最高工資", min(sal) "最低工資" from emp;

/*入職最早,入職最晚員工*/
select max(hiredate) "最晚入職時間", min(hiredate) "最早入職時間" from emp;

多行函數:count/sum/avg/max/min

/*按部門求出該部門平均工資,且平均工資取整數,採用截斷*/
select deptno "部門編號", trunc(avg(sal), 0) "部門平均工資"
  from emp
 group by deptno;

/*查詢部門平均工資大於2000元的部門*/
select deptno "部門編號", trunc(avg(sal), 0) "部門平均工資"
  from emp
 group by deptno
having trunc(avg(sal), 0) > 2000;

/*按部門平均工資降序排列*/
select deptno "部門編號", trunc(avg(sal), 0) "部門平均工資"
  from emp
 group by deptno
having trunc(avg(sal), 0) > 2000
 order by 2 desc;

/*除10號部門外,查詢部門平均工資大於2000元的部門,方式一【having deptno<>10】*/
select deptno, avg(sal) from emp group by deptno having deptno <> 10;

/*除10號部門外,查詢部門平均工資大於2000元的部門,方式二【where deptno<>10】  提倡*/
select deptno, avg(sal) from emp where deptno <> 10 group by deptno;

/*顯示部門平均工資的最大值*/
select max(avg(sal)) "部門平均工資的最大值" from emp group by deptno;

/*思考:顯示部門平均工資的最大值和該部門編號?*/
select max(avg(sal)) "部門平均工資的最大值", deptno "部門編號"
  from emp
 group by deptno;
錯誤

group by 子句的細節:
1)在select子句中出現的非多行函數的所有列,【必須】出現在group by子句中
2)在group by子句中出現的所有列,【可出現可不現】在select子句中

where和having的區別:
where:
1)行過濾器
2)針對原始的記錄
3)跟在from後面
4)where可省
5)先執行

having:
1)組過濾器
2)針對分組後的記錄
3)跟在group by後面
4)having可省
5)後執行

oracle中綜合語法:
1)select子句-----必須
2)from子句-------必須,不知寫什麼表了,就寫dual(啞表)
3)where子句------可選
4)group by子句---可選
5)having子句-----可選
6)order by 子句--可選,如果出現列名,別名,表達式,欄位

三、多表查詢

/*員工表emp和部門表dept的笛卡爾集(笛卡爾集表=列數之和,行數之積,笛卡爾集表內中有些數據是不符合要求的)*/
select emp.ename, dept.dname from emp, dept;

/*使用等值連接/內連接(只能使用=號),顯示員工的編號,姓名,部門名,使用表別名簡化*/
select emp.empno, emp.ename, dept.dname, dept.deptno
  from emp, dept
 where emp.deptno = dept.deptno;

/*使用非等值連接(不能使用=號,其它符號可以,例如:>=,<=,<>,betwen and等),顯示員工的編號,姓名,月薪,工資級別*/
select e.empno, e.ename, e.sal, s.grade
  from emp e, salgrade s
 where e.sal between s.losal and s.hisal;

內連接查詢:只能查詢出符合條件的記錄
外連接查詢:既能查詢出符合條件的記錄,也能根據一方強行將另一個方查詢出來

使用外連接,按部門10,20,30,40號,統計各部門員工人數,要求顯示部門號,部門名,人數
部門號      部門名                  人數
10            ACCOUNTING       3
20            RESEARCH           5
30            SALES                   6
40            OPERATIONS        0

等值連接/非等值連接/內連接:只會查詢出多張表中,根據某個欄位匹配,符合條件的記錄,不符合條件的記錄是不會存在的

/*左外連接[是oracle專用的,不是SQL99規則]*/
select dept.deptno "部門號", dept.dname "部門名", count(emp.empno) "人數"
  from dept, emp
 where dept.deptno = emp.deptno(+)
 group by dept.deptno, dept.dname;

/*右外連接*/
select dept.deptno "部門號", dept.dname "部門名", count(emp.empno) "人數"
  from dept, emp
 where emp.deptno(+) = dept.deptno
 group by dept.deptno, dept.dname;

/*使用左外連接,按部門10,20,30,40號,統計各部門員工人數,要求顯示部門號,部門名,人數,且按人數降序排列*/
select dept.deptno "部門號", dept.dname "部門名", count(emp.empno) "人數"
  from dept, emp
 where dept.deptno = emp.deptno(+)
 group by dept.deptno, dept.dname
 order by 3 desc;

/*使用自連接,顯示"SMITH的上級是FORD"這種格式*/
select users.ename || '的上級是' || boss.ename
  from emp users, emp boss
 where users.mgr = boss.empno;
只有13條記錄,不含有KING

/*基於上述問題,將KING的上級是“”顯示出來*/
select users.ename || '的上級是' || boss.ename
  from emp users, emp boss
 where users.mgr = boss.empno(+);
14條記錄
註意:自連接也用到內連接和外連接

四、子查詢

子查詢的作用:查詢條件未知的事物

查詢條件已知的問題:例如:查詢工資為800的員工信息
查詢條件未知的問題:例如:查詢工資為20號部門平均工資的員工信息
一個條件未知的問題,可以分解為多個條件已知的問題

/*查詢工資比WARD高的員工信息*/
第一:查詢WARD的工資?
select sal from emp where ename = 'WARD';
第二:查詢工資比1250高的員工信息?
select * from emp where sal > 1250;
子查詢:
select * from emp where sal > (select sal from emp where ename = 'WARD');

/*查詢部門名為'SALES'的員工信息(方式一:子查詢)*/
第一:查詢部門名為'SALES'的編號?
select deptno from dept where dname = 'SALES';
第二:查詢部門號為30的員工信息? 
select * from emp where deptno = 30;
子查詢:
select *
  from emp
 where deptno = (select deptno from dept where dname = 'SALES');

子查詢細節:
1)子查詢與父查詢可以針對同一張表
2)子查詢與父查詢可以針對不同張表
3) 子查詢與父查詢在傳統參數時,數量要相同
4) 子查詢與父查詢在傳統參數時,類型要相同
5) 子查詢與父查詢在傳統參數時,含義要相同

/*查詢部門名為'SALES'的員工信息(方式二:多表查詢)*/
select emp.*
  from dept, emp
 where (dept.deptno = emp.deptno)
   and (dept.dname = 'SALES');

/*查詢每個員工編號,姓名,部門名,工資等級(三表查詢,這三張表並無外健關聯)*/
select e.empno, e.ename, d.dname, s.grade
  from emp e, dept d, salgrade s
 where (e.deptno = d.deptno)
   and (e.sal between s.losal and s.hisal);

/*查詢工資最低的員工信息(單行子查詢,使用=號)*/
第一:查詢出工資最低是多少?
select min(sal) from emp;
第二:查詢工資為800的員工信息?
select * from emp where sal = 800;
子查詢:
select * from emp where sal = (select min(sal) from emp);

/*查詢部門名為'ACCOUNTING'或'SALES'的員工信息(多行子查詢,使用in關鍵字)*/  
第一:查詢部門名為'ACCOUNTING''SALES'的部門編號?
select deptno from dept where dname in ('ACCOUNTING','SALES');
第二:查詢部門號為10或30號的員工信息?
select * from emp where deptno in (10,30);
子查詢:
select *
  from emp
 where deptno in
       (select deptno from dept where dname in ('ACCOUNTING', 'SALES'));

/*查詢工資比20號部門【任意any】一個員工工資【低<】的員工信息(多行子查詢,使用any關鍵字)*/ 
第一:查詢20號部門的所有工資?
select sal from emp where deptno = 20;
第二:查詢工資比(800,2975,3000,1100,3000)任意一個低的員工信息?
select * from emp where sal < any (800,2975,3000,1100,3000);   
在oracle看來,<any就等於<集合中最大的那個值
子查詢:
select * from emp where sal < any (select sal from emp where deptno = 20);

/*查詢工資比30號部門【所有all】員工【低<】的員工信息(多行子查詢,使用all關鍵字)*/ 
第一:查詢出30部門所有員工的工資?    
select sal from emp where deptno = 30;
第二:查詢工資比(1600,1250,1250,2850,1500,950)中所有的工資都低的員工信息?
select * from emp where sal <all (1600,1250,1250,2850,1500,950);
子查詢:
select * from emp where sal < all (select sal from emp where deptno = 30);

註意:不容易理解的幾個概念:
單行函數:輸入一個參數,輸出一個結果
多行函數:掃描多個參數,輸出一個結果

單行子查詢:子查詢只會返回一個結果,例如:800,父查詢用=、<>、>=、<=這些符號來比較
多行子查詢:子查詢會返回多於一個結果,例如:30,20,父查詢用in、any、all這些符號來比較

當多表查詢,子查詢同時能解決問題時,按如下優先方案選擇:

多表查詢-->子查詢
註意:上述結果不是說多表查詢可以替代子查詢,某些情況下,只能用子查詢解決,例如:oracle分頁

五、集合查詢

/*使用並集運算,查詢20號部門或30號部門的員工信息*/
select *
  from emp
 where deptno = 20
union
select *
  from emp
 where deptno = 30;
註意:
union:二個集合中,如果都有相同的,取其一
union all:二個集合中,如果都有相同的,都取

/*使用set time/timing on,打開時間的開關*/
set time on;
set time off;

/*使用set tim/timing off,關閉時間的開關*/
set timing on;
set timint off;

/*使用交集運算[intersect],查詢工資在1000-2000和1500-2500之間的員工信息(方式一)*/
select *
  from emp
 where sal between 1000 and 2000
intersect
select *
  from emp
 where sal between 1500 and 2500;

/*用where行過濾,查詢工資在1000-2000和1500-2500之間的員工信息(方式二)*/
select *
  from emp
 where (sal between 1000 and 2000)
   and (sal between 1500 and 2500);

/*使用差集運算[minus],查詢工資在1000-2000,但不在1500-2500之間的員工信息(方式一)*/
select *
  from emp
 where sal between 1000 and 2000
minus
select *
  from emp
 where sal between 1500 and 2500;

/*使用where行過濾,查詢工資在1000-2000,但不在1500-2500之間的員工信息(方式二)*/
select *
  from emp
 where (sal between 1000 and 2000)
   and (sal not between 1500 and 2500);



集合查詢的細節:
/*1)集合操作時,必須確保集合列數是相等*/
select empno, ename, sal, comm
  from emp
 where deptno = 20
union
select empno, ename, sal
  from emp
 where deptno = 30;
錯,因為列數不一樣

/*2)集合操作時,必須確保集合列類型對應相同*/
select empno, ename, sal, comm
  from emp
 where deptno = 20
union
select empno, ename, sal, hiredate
  from emp
 where deptno = 30;
錯,因為集合類型不一樣

/*3)A union B union C = C union B union A*/
select *
  from emp
 where deptno = 10
union
select *
  from emp
 where deptno = 20
union
select *
  from emp
 where deptno = 30;

/*4)當多個集合操作時,結果的列名由第一個集合列名決定*/
select empno "編號", ename "姓名", sal "薪水"
  from emp
 where deptno = 20
union
select empno, ename, sal
  from emp
 where deptno = 10;

總結:當多表查詢,子查詢,集合查詢都能完成同樣任務時,按如下優化方案選擇:多表查詢->子查詢->集合查詢

六、Oracle的分頁

介紹Oracle之前,我們先介紹一些MySql分頁和Hibernate分頁,代碼如下:

回顧mysql分頁
用limit關鍵字 
/*查詢users表中前二條記錄*/
select * from users limit 0,2select * from users limit 2;
0表示第一條記錄的索引號,索引號從0開始
2表示最多選取二個記錄

/*查詢出users前三條記錄*/
select * from users limit 0,3select * from users limit 3

/*查詢出users第2條到第4條記錄*/
select * from users limit 1,3; 

回顧hibernate分頁API
Query.setFirstResult(0);
Query.setMaxResult(3);

並且想要瞭解Oracle的分頁之前,我們還需要知道rownum概念,什麼是rownum,有何特點?
1)rownum是oracle專用的關健字
2)rownum與表在一起,表亡它亡,表在它在
3)rownum在預設情況下,從表中是查不出來的
4)只有在select子句中,明確寫出rownum才能顯示出來
5)rownum是number類型,且唯一連續
6)rownum最小值是1,最大值與你的記錄條數相同
7)rownum也能參與關係運算
   * rownum = 1    有值
   * rownum < 5    有值
   * rownum <=5    有值     
   * rownum > 2    無值     
   * rownum >=2    無值
   * rownum <>2    有值 與  rownum < 2 相同
   * rownum = 2    無值
8)基於rownum的特性,我們通常rownum只用於<或<=關係運算

/*顯示emp表中3-8條記錄(方式一:使用集合減運算)*/
select rownum "偽列", emp.*
  from emp
 where rownum <= 8
minus
select rownum, emp.*
  from emp
 where rownum <= 2;

/*顯示emp表中3-8條記錄(方式二:使用子查詢,在from子句中使用,重點)*/
select xx.*
  from (select rownum ids, emp.* from emp where rownum <= 8) xx
 where ids >= 2;
註意:在子查詢中的別名,不可加""引號

/*顯示emp表中5-9條記錄*/
select yy.*
  from (select rownum ids, emp.* from emp where rownum <= 9) yy
 where ids >= 5;
註意:在項目中,from後臺可能有真實表名,也可能用子查詢看作的表名,同時真實表和子查詢看作的表要做連接查詢

七、創建表和約束

/*回顧MySQL創建表語句users(id整型/name字元串/birthday日期型,預設今天)*/
drop table if exists users;
create table if not exists users(
   id int(5) auto_increment primary key,
   name varchar(4) not null,
   birthday date default '2015-4-27'
);

/*使用oracleSQL,創建用戶表users(id整型/name字元串/birthday日期/sal整型,預設今天)*/
create table users(
  id number(5) primary key,
  name varchar2(8) not null unique,
  sal number(6,2) not null,
  birthday date default sysdate
);

/*進入回收站*/
drop table users;

/*查詢回收站中的對象*/
show recyclebin;

/*閃回,即將回收站還原*/
flashback table 表名 to before drop;
flashback table 表名 to before drop rename to  新表名;

/*徹底刪除users表*/
drop table users purge;

/*清空回收站*/
purge recyclebin;
  
/*測試如下類型*/1number(5):
insert into users(id,name,sal) values(1,'A',6666.66);     
insert into users(id,name,sal) values(11,'AA',6666.66);     
insert into users(id,name,sal) values(111,'AAA',6666.66);     
insert into users(id,name,sal) values(1111,'AAAA',6666.66);     
insert into users(id,name,sal) values(99999,'AAAAA',6666.66);     
insert into users(id,name,sal) values(100000,'AAAAAA',6666.66); 錯
5表示最多存99999    

(2number(6,2):
col sal for 9999.99 
insert into users(id,name,sal) values(1,'A',6.66);     
insert into users(id,name,sal) values(11,'AA',66.666);     
insert into users(id,name,sal) values(111,'AAA',666.6666);     
insert into users(id,name,sal) values(1111,'AAAA',6666.66666);     
insert into users(id,name,sal) values(11111,'AAAAA',66666.666666);錯 
number(6,2)
其中2表示最多顯示2位小數,採用四捨五入,不足位數補0,同時要設置col ... for ... 
其中6表示小數+整數不多於6位
其中整數位數不得多於4位,可以等於4位

(3varchar2(8):
insert into users(id,name,sal) values(1,'A',7777.77);     
insert into users(id,name,sal) values(2,'AA',7777.77);     
insert into users(id,name,sal) values(3,'AAA',7777.77);     
insert into users(id,name,sal) values(4,'AAAA',7777.77);  
insert into users(id,name,sal) values(5,'AAAAA',7777.77);  
insert into users(id,name,sal) values(6,'AAAAAA	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 模擬器網速調整: 限制時輸入下麵兩行,根據需要修改下麵的數字: sudo ipfw pipe 1 config bw 350kbit/s plr 0.05 delay 10000ms; sudo ipfw add pipe 1 dst-port http 不想再去限制網速是,輸入下麵的命令行: su ...
  • 記錄兩次事情: 第一個給view添加動畫效果,需要保證view是可以獲取焦點的 第二個給listview,GridView設置選擇器 listselector時,要保證他的子item無背景,否則選擇器的背景會被子item的背景擋住 ...
  • 最近在學慕課網上的一個實戰課程,期間有一個智能聊天機器人模塊。 聊天界面通過 ListView 顯示,用 Adapter 載入。一般來說,單對單的聊天,兩者發出的話分別列在聊天頁面的左右兩邊。所以,在 Adapter 里需要設置一個 Type 來區分發送方和接收方,從而正確顯示左右。 在課程視頻里, ...
  • UITableView用得較多,遇到的情況也較多,單獨記錄一篇。 一、零散的技巧 二、取cell 三、cell高度 四、導航欄、TableView常見問題相關 一、零散的技巧 1、 cell的選中效果是cell的屬性,可以有的有,無的無。 2、cell的下劃線是Table的屬性,全部有,或全部無。 ...
  • Android精選源碼 仿MIUI果凍視圖-BouncingJellyView 一個快速易用的動態主題框架 android動畫效果集合源碼 android使用Kotlin開發的Dribbble客戶端 android一款開源社交app源碼 android實現RecyclerView頂部懸浮效果源碼 開 ...
  • Phoenix簡介及安裝部署使用 ...
  • /************************************************************ * 標題:MS SQLServer 批量附加資料庫 * 說明:請根據下麵的註釋使用此腳本 * 時間: 2015/7/13 11:16:41 ******************... ...
  • 這幾天剛好碰到數據的分頁查詢,覺得不錯,Mark一下,方法有兩種,都是使用select top,效率如何就不在這討論 方法1:利用select top配合not in(或者not exists),查詢第n頁的時候,過濾掉n-1頁的數據即可,示例假設每頁查詢數量為5,查詢第3頁的數據; Select ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...