一、簡單查詢:
1、查詢數據表的所有列:
SELECT * FROM 表名;
SELECT 列名,列名.... FROM 表名;
2、起別名:
SELECT 列名 [AS 別名],列名 別名....
FROM 表名;
---正常
SELECT ename AS 員工姓名,sal salary
FROM emp;
---別名是關鍵字,別名需要用雙引號引起來
SELECT ename "select",sal "from"
FROM emp;
---別名中間存在空格,別名需要用雙引號引起來
SELECT ename "employee name",sal
FROM emp;
3、distinct:去重
---查詢emp表中的不同職務
SELECT DISTINCT job
FROM emp;
---查詢emp表中每個部門的不同職務
SELECT DISTINCT deptno,job
FROM emp;
---查詢emp表中不同部門的不同職務
SELECT DISTINCT deptno,DISTINCT job
FROM emp; ---錯誤
注意:select后面,多列去重,在所有列的前面寫一個distinct關鍵字即可
4、|| 連接輸出
---將每個員工的信息輸出為如下格式:
姓名為:xxxx,工資為:xxx。
字符串和日期用單引號引起來的。
SELECT '姓名為:'|| ename || ',工資為:' || sal || '。' 員工信息
FROM emp;
5、四則運算:
---查詢員工的姓名和年薪
SELECT ename,sal*12 年薪
FROM emp;
SELECT ename,(sal+comm)*12 年薪
FROM emp;
---當與null值參與運算或是比較時,結果一定為null
nvl(agr1,arg2):判斷arg1是否為Null,如果不為null,結果為arg1,如果為null,結果為arg2
SELECT ename,(sal+nvl(comm,0))*12 年薪
FROM emp;
1.員工轉正后,月薪上調20%,請查詢出所有員工轉正后的月薪。
SELECT SAL*1.2 "員工轉正后的月薪"
FROM EMP
2.員工試用期6個月,轉正后月薪上調20%,請查詢出所有員工工作第一年的年薪所得(不考慮獎金部分,年薪的試用期6個月的月薪+轉正后6個月的月薪)
SELECT SAL*6+SAL*1.2*6 "工作第一年年薪"
FROM EMP
1.員工試用期6個月,轉正后月薪上調20%,請查詢出所有員工工作第一年的所有收入(需考慮獎金部分),要求顯示列標題為員工姓名,工資收入,獎金收入,總收入。
SELECT ENAME 員工姓名,SAL*6+SAL*1.2*6 工資收入,nvl(comm,0) 獎金收入,(SAL*6+SAL*1.2*6+nvl(comm,0)) 總收入
FROM EMP
1.員工試用期6個月,轉正后月薪上調20%,請查詢出所有員工工作第一年的所有收入(需考慮獎金部分),要求顯示格式為:XXX的第一年總收入為XXX
SELECT ENAME||'的第一年總收入為'||(SAL*6+SAL*1.2*6+nvl(comm,0))
FROM EMP
二、排序:
SELECT 列名 [AS 別名],列名 別名....
FROM 表名
ORDER BY 排序字段 ASC|DESC,排序字段 ASC|DESC...;
排序字段:列名,列的別名,列的順序號,函數結果
SELECT *
FROM emp
ORDER BY deptno,sal desc;
SELECT ename a,deptno b,sal c
FROM emp
ORDER BY b,c desc;
SELECT ename a,deptno b,sal c
FROM emp
ORDER BY 2,3 desc;
---按照員工的部門編號 升序排序,部門相同按照獎金降序排序
SELECT ename a,deptno b,sal c,comm
FROM emp
ORDER BY 2,nvl(comm,0) desc;
三、限定查詢
SELECT 列名 [AS 別名],列名 別名....
FROM 表名
WHERE 條件
ORDER BY 排序字段 ASC|DESC,排序字段 ASC|DESC...;
1、關系運算符:
>,<,<=,>=,=,<>,!=
可以比較數據類型:數值型,字符串,日期
---查詢員工的工資大於2500的員工信息
SELECT *
FROM emp
WHERE sal>2500;
---查詢員工姓名 為SMITH的員工信息
SELECT *
FROM emp
WHERE ename='SMITH';
---查詢在1982年之后入職的員工信息
'日-月-年'
'DD-MM-RR'
SELECT *
FROM emp
WHERE hiredate > '31-12月-1982';
2、邏輯運算符:
and:與
or:或
not:非
not>and>or
---查詢員工的職務是MANAGER或是SALESMAN,且工資大於1500的員工的姓名,職務,工資
SELECT ename,job,sal
FROM emp
WHERE (job='MANAGER' OR JOB = 'SALESMAN') and sal>1500;
3、between...and... 閉區間
語法:字段名 [not] between 最小值 and 最大值
--查詢在1982年入職的員工信息
SELECT *
FROM emp
WHERE hiredate between '1-1月-1982' and '31-12月-1982';
4、in:集合運算
語法:字段名 [not] in(值1,值2,值3...)
---查詢員工的職務是MANAGER或是SALESMAN,且工資大於1500的員工的姓名,職務,工資
SELECT ename,job,sal
FROM emp
WHERE job in('MANAGER','SALESMAN') and sal>1500;
5、is null:沒有
is not null:有
---查詢沒有領導的員工信息
SELECT *
FROM emp
WHERE mgr is null;
---查詢獎金不為null的員工信息
SELECT *
FROM emp
WHERE comm is not null;
6、like:模糊查詢
語法:字段名 [not] like '匹配串' [ESCAPE '轉義字符']
_:任意1個字符
%:0個或 多個任意字段
---查詢員工姓名中包含S的員工姓名
SELECT ename
FROM emp
WHERE ename like '%S%';
insert into emp(empno,ename,sal,comm,deptno) values(2222,'li_si',2100,200,30);
commit;
---查詢員工姓名中包含%的員工的姓名
SELECT ename
FROM emp
WHERE ename like '%#%%' ESCAPE '#';
SELECT ename
FROM emp
WHERE ename like '%#_%' ESCAPE '#';
SELECT ename
FROM emp
WHERE ename like '%!%%' ESCAPE '!';
SELECT ename
FROM emp
WHERE ename like '%a_%' ESCAPE 'a';
1.查詢入職時間在1982-7-9之后,並且不從事SALESMAN工作的員工姓名、入職時間、職位。
select ename,hiredate,job
from emp
where hiredate>'9-7月-1982' and job<>'SALESMAN'
2.查詢員工姓名的第三個字母是a的員工姓名。
select ename
from emp
where ename like '__a%';
3.查詢除了10、20號部門以外的員工姓名、部門編號。
select ename,deptno
from emp
where deptno not in(10,20);
4.查詢部門號為30號員工的信息,先按工資降序排序,再按姓名升序排序。
select *
from emp
order by sal desc,ename
5.查詢沒有上級的員工(經理號為空)的員工姓名。
select ename
from emp
where mgr is null
6.查詢工資大於等於4500並且部門為10或者20的員工的姓名\工資、部門編號。
select ename,sal,deptno
from emp
where sal>=4500 and deptno in(10,20)
四、單行函數
字符函數,數值函數,日期函數,轉換函數,通用函數
1、字符函數:
(01) upper():轉大寫
(02) lower():轉小寫
(03) initcap():轉首字符大寫,其它字符小寫
(04) length():長度
DUAL:sys用戶的一張表,只有一個字段,sys創建了該表的公共同義詞
SELECT upper(ename),lower(ename),initcap(ename),length(ename)
FROM emp;
(05)trim():去首尾的空格
SELECT length(trim(' abc '))
FROM dual;
trim(letter from str):去掉str首尾的字母letter
SELECT trim('h' from 'hello')
FROM dual;
SELECT trim('t' from 'test')
FROM dual;
SELECT trim('t' from 'ttttttttesttttttt')
FROM dual;
(06)concat(str1,str2):連接字符串 ||
SELECT concat(ename,job)
FROM emp;
SELECT concat(concat(ename,job),hiredate)
FROM emp;
(07)instr(str1,str2,[n1,n2]):返回str2在str1中的位置,從n1開始查找第n2次出現的位置
沒在str1存在的時,返回0
SELECT instr('hello world','l')
FROM dual;
SELECT instr('hello world','l',1,2)
FROM dual;
SELECT instr('hello world','a')
FROM dual;
---查詢員工姓名中不含有A的員工姓名
SELECT ename
FROM emp
WHERE instr(ename,'A')=0;
SELECT instr('hello world','world')
FROM dual;
(08)replace(str1,str2,str3):將str1中的str2替換為str3
SELECT replace('abc aaa abc bbb abc ccc','abc','ABC')
FROM dual;
(09)substr(str,loc,length):截取子串,從str的loc開始截取長度為length的子串
--從首位截取,起始位置可以為0或者1
SELECT substr('hello world',1,3)
FROM dual;
SELECT substr('hello world',0,3)
FROM dual;
---截取到字符串的尾部,第三個參數省略
SELECT substr('hello world',5)
FROM dual;
---截取中間子串
SELECT substr('hello world',4,3)
FROM dual;
(10)lpad(str1,length,str2):判斷 str1的長度是否等於Length,如果小於length,在str1的左邊補充str2,直到長度等於length為止。
(11)rpad(str1,length,str2):判斷 str1的長度是否等於Length,如果小於length,在str1的右邊補充str2,直到長度等於length為止。
---判斷hello的長度是否等於10,如果 不等於,在左邊補充#
SELECT lpad('hello',10,'#')
FROM dual;
SELECT lpad('hellohellohello',10,'#')
FROM dual;
SELECT lpad('hello',10,'#$')
FROM dual;
1.寫一個查詢,用首字母大寫,其它字母小寫顯示雇員的 ename,顯示名字的長度,並給每列一個適當的標簽,
條件是滿足所有雇員名字的開始字母是J、A 或 M 的雇員,並對查詢結果按雇員的ename升序排序。(提示:使用initcap、length、substr)
SELECT initcap(ename),LENGTH(ename)
FROM emp
WHERE substr(ename,1,1) IN('J','A','M')
ORDER BY 1;
1.查詢員工姓名中中包含大寫或小寫字母A的員工姓名。
SELECT ename
FROM emp
WHERE upper(ename) like '%A%';
---查詢emp表中職務是clerk的員工姓名
SELECT ename
FROM emp
WHERE lower(job)='clerk';
2.查詢部門編號為10或20,入職日期在81年5月1日之后,並且姓名中包含大寫字母A的員工姓名,
員工姓名長度(提示,要求使用INSTR函數,不能使用like進行判斷)
3.查詢每個職工的編號,姓名,工資
要求將查詢到的數據按照一定的格式合並成一個字符串.
前10位:編號,不足部分用*填充,左對齊
中間10位:姓名,不足部分用*填充,左對齊
后10位:工資,不足部分用*填充,右對齊
SELECT rpad(empno,10,'*') || rpad(ename,10,'*') || lpad(sal,10,'*')
FROM emp;
2、數值函數
(01)round(num,p):四舍五入
p=0:round(num),四舍五入為整數
SELECT round(455.55)
FROM dual;
p>0:四舍五入到小數點右邊第P位
SELECT round(455.55,1)
FROM dual;
p<0:從小數點左邊的第|p|位進行四舍五入
SELECT round(455.55,-1)
FROM dual;
SELECT round(455.55,-3)
FROM dual;
SELECT round(555.55,-3)
FROM dual;
(02)trunc(num,p):截斷
p=0:trunc(num),截斷為整數
SELECT trunc(455.55)
FROM dual;
p>0:截斷到小數點右邊第p位
SELECT trunc(455.55,1)
FROM dual;
p<0:從小數點左邊的第|p|位進行截斷
SELECT trunc(455.55,-1)
FROM dual;
(03):mod(num1,num2):求余
SELECT mod(3,2)
FROM dual;
SELECT mod(3,0)
FROM dual;
3、日期函數
規則: 日期-日期=天數
日期+天數=日期
當前系統日期:sysdate
(01)months_between(date1,date2):返回兩個日期之間相差的月份。如果date1>date2,返回正數,反之,返回是負數
SELECT trunc(months_between(SYSDATE,'1-1月-2000'))
FROM dual;
---統計 emp表中每人入職了多少個月?
SELECT ename,trunc(months_between(SYSDATE,hiredate))
FROM emp;
---統計 每個人到目前為止入職了多少年零多少月零多少天?
SELECT trunc(months_between(SYSDATE,hiredate)/12) 年, trunc(mod((SYSDATE-hiredate),365)/30) 月,
trunc(mod(mod((SYSDATE-hiredate),365),30)) 天
FROM emp;
(02)next_day(DATE,weekday):返回指定日期的下個星期幾是什么日期
SELECT next_day(SYSDATE,'星期一')
FROM dual;
(03) last_day(DATE):返回指定日期的所在月份的最后一天
SELECT last_day(SYSDATE)
FROM dual;
(04)add_months(DATE,months):在指定日期上增加若干個月后的日期
SELECT add_months(sysdate,4)
FROM dual;
(05)EXTRACT([MONTH DAY YEAR] FROM DATE):從指定日期中取出日期中的年,月,日
SELECT EXTRACT(MONTH FROM SYSDATE)
FROM dual;
SELECT EXTRACT(year FROM SYSDATE)
FROM dual;
---查詢在1982年入職的員工信息
SELECT *
FROM emp
WHERE extract(year from hiredate)=1982;
---在一年月前半年入職的員工信息
SELECT *
FROM emp
WHERE EXTRACT(MONTH FROM hiredate)<=6;
(06)round(DATE,fmt):
(07)trunc(DATE,fmt):
fmt:
CC:世紀
YY:年
MM:月
DD:日
HH:時
SELECT round(SYSDATE,'MM')
FROM dual;
SELECT round(to_date('17-3月-2018'),'MM')
FROM dual;
4、轉換函數
(01)to_char():轉為字符串
將日期轉為字符串:
to_char(DATE,'format'):將日期轉為固定格式的字符串
常用的格式:
yyyy:年
mm:月
dd:日
day:星期
hh:時 hh24:24小時制
mi:分
ss:秒
mon:月
SELECT to_char(SYSDATE,'yyyy-mm-dd hh24:mi:ss day')
FROM dual;
SELECT to_char(SYSDATE,'yyyy')
FROM dual;
SELECT ename,hiredate
FROM emp
WHERE to_char(hiredate,'yyyy')='1982';
將數值 轉為字符串:
to_char(NUMBER,'format'):將指定的數據轉為固定格式的字符串
SELECT to_char(455.55)
FROM dual;
常見的格式:
.:小數點
9:任意數字
,:千位符
L:本地貨幣符號
$:美元
SELECT to_char(4555.55,'L999,999.99')
FROM dual;
(02)to_number(str,'format'):轉為數值,將固定格式的字符串轉為數值
SELECT TO_NUMBER('¥4,555.55','L9,999.99')
FROM dual;
(03)to_date(str,'format'):轉為日期,將固定格式的字符串轉為日期
SELECT to_date('21-12-2017','dd-mm-yyyy')
FROM dual;
5、通用函數:
(01)nvl():
(02) nvl2(arg1,arg2,arg3):判斷arg1是否為null,如果不為Null,返回arg2,如果為Null,返回arg3
SELECT ename,comm,nvl2(comm,comm,0)
FROM emp;
---查詢員工的姓名,獎金,如果獎金為null,輸出為“No comm.”
SELECT ename,comm,nvl2(comm,to_char(comm),'No comm.')
FROM emp;
(03)decode():類似於等值判定,swith
語法:decode(exp/comm,值1,結果1,值2,結果2....,值n,結果n,結果m);
---判定員工姓名中含A或a的位置,如果位置在首位,顯示“A在首位”,如果位置在末尾,顯示“A在末尾”,如果A在中間,顯示"A在中間",否則,“不包含A”
SELECT ename,decode(instr(upper(ename),'A'),1,'A在首位',0,'不包含A',LENGTH(ename),'A在末尾','A在中間')
FROM emp;
(04):CASE():
格式一:
CASE WHEN 條件1 THEN 結果1
WHEN 條件2 THEN 結果2
....
WHEN 條件N THEN 結果n
ELSE 結果m
END;
SELECT ename,CASE WHEN upper(ename) LIKE 'A%' THEN 'A在首位'
WHEN upper(ename) LIKE '%A' THEN 'A在末尾'
WHEN upper(ename) NOT LIKE '%A%' THEN '不包含A'
ELSE 'A在中間'
END
FROM emp;
格式二:
CASE 表達式/列名 WHEN 值1 THEN 結果1
WHEN 值2 THEN 結果2
。。。
WHEN 值n THEN 結果n
ELSE 結果m
END
作業:
---PPT第三章
---1.查詢入職時間在1982-7-9之后,並且不從事SALESMAN工作的員工姓名、入職時間、職位。
select ename,hiredate,job
from emp
where hiredate > '9-7月-1982' and job !='salesman'
---2.查詢員工姓名的第三個字母是a的員工姓名。
select ename
from emp
where ename like '__A%';
---3.查詢除了10、20號部門以外的員工姓名、部門編號。
select ename ,deptno
from emp
where deptno not in(10,20)
---4.查詢部門號為30號員工的信息,先按工資降序排序,再按姓名升序排序。
select *
from emp
where deptno=30
order by sal desc ,ename ;
---5.查詢沒有上級的員工(經理號為空)的員工姓名。
select ename
from emp
where mgr is null;
---6.查詢工資大於等於4500並且部門為10或者20的員工的姓名\工資、部門編號。
select ename,sal,deptno
from emp
where sal>4500 and deptno in(10,20)
----PPT第四章
---1.計算2000年1月1日到現在有多少月,多少周(四舍五入)。
select round(months_between(SYSDATE,to_date('2000-1-1','yyyy-mm-dd'))) 月
,round(months_between(SYSDATE,to_date('2000-1-1','yyyy-mm-dd'))*4) 周
from dual;
---2.查詢員工ENAME的第三個字母是A的員工的信息(使用2個函數)。
select *
from emp
where substr(upper(ename),3,1)='A';
---3.使用trim函數將字符串‘hello’、‘ Hello ’、‘bllb’、‘ hello ’分別處理得到下列字符串ello、Hello、ll、hello。
select trim('h' from 'hello'),trim(' Hello '),trim('b' from 'bllb'),trim(' hello ')
from dual;
---4.將員工工資按如下格式顯示:123,234.00 RMB
select TO_char(sal,'999,999.99') || 'RMB'
from emp;
---5.查詢員工的姓名及其經理編號,要求對於沒有經理的顯示“No Manager”字符串。
select ename ,nvl2(mgr,to_char(mgr),'No Manager')
from emp;
---6.將員工的參加工作日期按如下格式顯示:月份/年份。
select to_char(hiredate,'mm/yyyy')
from emp;
---7.在員工表中查詢出員工的工資,並計算應交稅款:如果工資小於1000,稅率為0,如果工資大於等於1000並小於2000,稅率為10%,
---如果工資大於等於2000並小於3000,稅率為15%,如果工資大於等於3000,稅率為20%。
select sal 工資,CASE WHEN sal<1000 THEN sal
WHEN sal>=1000 and sal<2000 THEN sal*0.1
WHEN sal>=2000 and sal<3000 THEN sal*0.15
ELSE sal*0.2
END 應交稅款
from emp;
---8.創建一個查詢顯示所有雇員的 ename和 sal。格式化sal為 15 個字符長度,用 $ 左填充,列標簽 SALARY。
select ename,lpad(sal,15,'$') SALARY
from emp;
--文檔實驗二
--實驗步驟
---(1)創建一個查詢顯示工資大於2850美元的雇員的姓名及工資
select ename,sal
from emp
where sal>2850
---(2)顯示工資不在1500到2850美元之間的雇員的姓名及工資
select ename,sal
from emp
where sal not in(1500,2850)
---(3)顯示在10和30部門工作並且工資大於1500美元的雇員的姓名和工資,列標題顯示為Employee和Monthly Salary
select ename Employee,sal "Monthly Salary"
from emp
where deptno in(10,30) and sal>1500
---(4)顯示獎金比工資多10%以上的雇員的姓名、工資及獎金。
select ename,sal,comm
from emp
where comm>sal*1.1
--思考練習題
---1.創建一個查詢顯示雇員編號為7566的雇員的姓名和部門編號。
select ename,deptno
from emp
where empno=7566
---2.顯示受雇時間在February 20,1981和May 1,1981之間的雇員的姓名、工資、及受雇時間,並以受雇時間升序排列。
select ename,sal,hiredate
from emp
where hiredate between '20-2月-1981' and '1-5月-1981'
order by hiredate
---3.顯示在10號和30號部門工作的雇員的姓名及其部門編號,並以字母順序排列。
select ename,deptno
from emp
where deptno in(10,30)
order by ename;
---4.顯示所有受雇於1982年的雇員的姓名和受雇時間。
select ename,hiredate
from emp
where to_char(hiredate,'yyyy')=1982;
---5.顯示沒有上級管理員的雇員的姓名及其工作。
select ename,job
from emp
where mgr is null;
---6.顯示能掙得獎金的雇員的姓名、工資、獎金,並以工資和獎金降序排列。
select ename,sal,comm
from emp
where comm is not null
order by sal,comm desc;
---7.顯示姓名中第三個字母為A的雇員的姓名。
select ename
from emp
where substr(upper(ename),3,1)='A'
---8.顯示姓名中兩次出現字母L並且在30部門工作或者其管理員編號是7782的雇員的姓名。
select ename
from emp
where upper(ename) like '%L%L%' and (deptno=30 or mgr=7782)
---9.顯示工作為Clerk或Analyst並且工資不等於$1000、$3000、$5000的雇員的姓名、工作及工資。
select ename,job,sal
from emp
where job in('CLERK','ANALYST')and sal not in(1000,3000,5000)
--文檔實驗三
--實驗步驟
---(1)顯示雇員的編號、姓名、工資以及工資增長15%后的整數值(以New Salary作為列標題)
SELECT empno,ename,sal,round(sal*1.15) "New Salary"
from emp
---(2)在(1)的基礎上,增加一個列Increase顯示new salary和salary的差值
SELECT empno,ename,sal,round(sal*1.15) "New Salary",round(sal*1.15)-sal Increase
from emp
---(3)顯示雇員姓名並以*為指示符代表工資數額(列標題為EMPLOYEE_AND_THEIR_SALARIES),一個指示符代表一百美元,並以工資數額降序排列。
select ename,rpad('*',trunc(sal/100)-1,'*') EMPLOYEE_AND_THEIR_SALARIES
from emp
order by sal desc
--思考練習題
---1.編寫一個顯示當期日期的查詢,列標題為Date。
select SYSDATE "Date"
from dual
---2.顯示雇員姓名、受雇日期及工資復審日期(復審日期為受雇后6個月后的第一個星期一),復審日期以列標題REVIEW顯示。
select ename,hiredate,next_day(add_months(hiredate,6),'星期一') REVIEW
from emp
---3.顯示每個雇員的姓名並計算出從受雇日期起到目前一共工作了多少個月,以列標題MONTHS_WORKED顯示月數(四舍五入),輸出以月數升序排列。
select ename ,round(months_between(SYSDATE,hiredate)) MONTHS_WORKED
from emp
order by months_between(SYSDATE,hiredate)
---4.編寫一個以下面的形式輸出的查詢:
---<employee name> earns <salary> monthly but wants <3 times salary>.
---列標題為Dream Salaries。
select '<' || ename || '> earns <'|| sal || '> monthly but wants <' || 3*sal || '>'
from emp;
---5.創建一個查詢顯示每個雇員的姓名及工資(列標題為SALARY),工資的顯示模式為:占15個字符的寬度,對於不夠位數的以$填充。
select ename,rpad(sal,15,'$') SALARY
from emp
---6.編寫一個查詢顯示名字以J、A、M開頭的雇員的姓名及姓名所占的字符數,姓名的顯示格式為第一個字母大寫其他字母小寫,為每個列設置合適的列標題。
select initcap(ename) 姓名,length(ename) 姓名長度
from emp
where substr(ename,1,1) in('J','A','M')
---7.顯示雇員的姓名、受雇日期及受雇當天是星期幾(列標題為DAY),並以DAY升序排列
select ename,hiredate,to_char(hiredate,'day') "DAY"
from emp
order by to_char(hiredate,'day')
---8.創建一個查詢顯示雇員姓名及其獎金(列標題為COMM),如果該雇員不能獲得獎金則以“No Commission.”顯示。
select ename,nvl2(comm,to_char(comm),'No Commission') COMM
from emp
