orcale 資料庫語句(二)
阿新 • • 發佈:2020-12-11
較複雜查詢
先在使用者表中新增工資和部門id兩列
alter table userinfo add sal number(10);
alter table userinfo add deptid number(4);
查詢工資總和
select sum(sal) salSum from userinfo;
分組求和(按部門id查工資總和)
select deptid,sum(sal) salSum from userinfo group by deptid;--按部門id分組
select deptid,status,sum(sal) salSum from userinfo group by deptid,status;--按部門id和狀態分組
select max(sal) salSum from userinfo;--查詢工資中最大值
select min(sal) salSum from userinfo;--查詢工資中最小值
合併結果集
select max(sal) salSum from userinfo--合併工資最大值和最小值
union
select min(sal) salSum from userinfo;
select * from userinfo where status=0 --合併狀態為0和狀態為1的資料,
union --沒有的列可以用相同的型別的數或字母代替
select id,name,password,status,0,0 from userinfo where status=1;
select * from userinfo where status=0--合併狀態為0和狀態為1的資料
union all
select * from userinfo where status=1;
去重查詢
select distinct status,name from userinfo;
按部門查詢平均工資
select deptid,avg(sal) avg,sum(sal) salSum,count (id) from userinfo group by deptid;
--為確保平均工資是正確的,按部門顯示出其部門的人數、總工資
查詢平均工資高於6000的部門(部門編號和平均工資)
select * from(
select deptid,avg(sal) avg,sum(sal) salSum,count(id) from userinfo group by deptid
)where avg>6000;--綜合使用,把查詢的各部門的平均工資的表當成總表,用where加條件實現該語句
工資高於bb
select * from userinfo where sal>(select sal from userinfo where name='bb');--將bb的工資查詢出來
--作為條件來實現查詢工資高於bb的
工資高於部門1所有使用者的資料
select * from userinfo where sal>(select max(sal) from userinfo where deptid='1');
--此語句工資高於部門1的所有使用者的資料,意思就是隻要高於部門1工資的最大值的就等於高於所有使用者了
工資高於部門1任一使用者的資料
select * from userinfo where sal>(select min(sal) from userinfo where deptid='1');
--與上句相反,要求只高於部門1的工資最小值就好
常用的函式
select id,name,status,decode(status,0,'登出',1,'正常',2,'特別') s_name from userinfo;
select u.*,decode(status,0,'登出',1,'正常',2,'特別')s_name from userinfo u;--輸出的根據值,0 為 登出 1 為正常 2 為特別
select u.*, nvl(phone,0) phone_name from userinfo u;--輸出的有就是原值,沒有就輸出0,輸出的值的型別應該與資料型別一致
select u.*, nvl2(phone,'有','無') phone_name from userinfo u;--輸出的有就是‘有’,沒有就是‘無’,輸出型別不受限制
select u.*, concat(id,name) from userinfo u;--拼接(這種只能倆個兩個拼接)
select u.*,(id||'-'||'name'||'-'||'status') from userinfo u--可以多個拼接,中間還能加字串;
select u.*,substr(name,2) from userinfo u;
select u.*,substr(name,2,3) from userinfo u;--擷取位置開始 (第一位就是1),擷取3位
select u.*,substr('abcdefg',2,3) from userinfo;--自己建立的字串也可以
select u.*,rpad(name,4) from userinfo u;
select u.*,rpad(name,4,'*') from userinfo u;--不夠四位的用‘*’填充
select u.*,instr(name,'d') from userinfo u;--包含‘d’的返回d的位置的值
select u.*,instr(name,'d',4) from userinfo u;--包含‘d’的返回d的位置的值,從第四位開始查詢
select u.*,instr(name,'d',4,2) from userinfo u;--包含‘d’的,從第四位開始查詢,第二次的值
--trim函式
--leading 開頭字元
--trailing 結尾字元
--both 開頭和結尾字元
--trim_character 去除的字元
--trim_source 修剪源
--如果指定leading引數,oracle資料庫將去除任何等於trim_character的開頭字元。
select trim(leading 'x' from 'xdylan') "test_trim" from dual;
--如果指定traling引數,oracle將去除任何等於trim_character的結尾字元。
select trim(trailing 'x' from 'dylanx') "test_trim" from dual;
--如果指定了both引數或者三個引數都未指定,oracle將去除任何等於trim_character的開頭和結尾字元。
--可寫可不寫,預設就是both
select trim(both 'x' from 'xdylanx') "test_trim" from dual;
select trim('x' from 'xdylanx') "test_trim" from dual;
--如果沒有指定trim_character引數,預設去除的值為空格。
select trim(both from ' dylan ') "test_trim" from dual;
--如果只指定修剪源(trim_source),oracle將去除trim_source的開頭和結尾的空格。
select trim(' dylan ') "test_trim" from dual;
--trim函式返回一個varchar2型別值。該值最大的長度等於trim_source的長度
--如果trim_source和trim_character有一個為null,則trim函式返回null。
select trim(trailing null from 'dylan ') "test_trim" from dual;
select trim(trailing 'd' from null ) "test_trim" from dual;
連線
先做準備工作,假設這是一個關於學生的資料庫,我們已經有了使用者表,現在還需要一個成績表
--建立成績表
create table result(
ID int primary key,
student_id int not null,
course_id int not null,
score int
);
--同時插入多條資料
--1
--由於insert all方式插入多條時,通過sequence獲取的值是同一個,不會自動獲取多個,所以id需要其他方式設定
insert all
into result values(1,'2','1','66')
into result values(2,'2','2','69')
into result(ID,student_id,course_id,score) values(3,'3','1','82')
select * from dual;
--insert all 還支援往不同的表裡插入資料
--dual是系統給的一個空表,在(一)中我們用於建立了序列
--2
insert into result (ID,student_id,course_id,score)
select 4,'3','2','93'from dual
union all select 5,'4','1','55'from dual
union all select 6,'111','1','55'from dual
交叉連線
select * from userinfo,student;
select * from userinfo cross join student;
select * from userinfo u,result r where u.id=r.student_id;
select distinct u.* from userinfo u,result r where u.id=r.student_id;
--distinct列出不同的,相同的會合並
內連線
select * from userinfo u join result r on u.id=r.student_id;
select * from userinfo u inner join result r on u.id=r.student_id;--inner可省略
在條件相同時交叉連線和內連線的查詢內容一樣
外連線:會以主表為主,沒有的地方為空
select * from userinfo u left join result r on u.id=r.student_id;--左外連線,以左邊的表為主表
select * from userinfo u left outer join result r on u.id=r.student_id;--outer可省略
select * from userinfo u right join result r on u.id=r.student_id;--右外連線,以右邊的表為主表
select * from userinfo u right outer join result r on u.id=r.student_id;--outer可省略
左外連線如圖所示
右外連線如圖所示
全連線
select * from userinfo u full join result r on u.id=r.student_id;
--查詢結果沒有的地方都會空著
如圖所示
自連線(查詢與aa狀態一致的使用者的資訊)
select * from userinfo where status=(select status from userinfo where name='aa');
select u1.* from userinfo u1,userinfo u2 where u1.status=u2.status and u2.name='aa';
select u1.* from userinfo u1 inner join userinfo u2 on u1.status=u2.status where u2.name='aa';
自然連線(要有一個同名列,根據同名列進行合併)
select * from userinfo u natural join result r;
如圖,因兩個表中都有id,id被合併了。
判斷
將狀態從數字轉換為漢字區分資料。
select u.*,
case to_char(status)
when '0' then '已刪除'
when '1' then '未稽核'
when '2' then '正常'
when null then '無'
end sta
from userinfo u;
已基本滿足效果,但不能處理資料為空的地方。
--推薦使用
select u.*,
case
when status='0' then '已刪除'
when status='1' then '未稽核'
when status='2' then '正常'
when status is null then '無'
end sta
from userinfo u;
改進之後,已經可以處理空值啦
今天你學費(hui)啦嗎?