SQL語句練習題(壹)

說明:

這個分類專欄是我學習SQL的筆記與總結,其內容包含

  • Linux下ORACLE的安裝
  • 筆記總結(思維導圖、文本)
  • 練習題(思路、注意事項)

練習題:

1、選擇部門30中的所有員工;      

2、列出所有辦事員(CLERK)的姓名,編號和部門編號;

3、找出獎金高於薪金的員工;

4、找出獎金高於薪金的60%的員工;

5、找出部門10中的所有經理(MANAGER)和部門20中所有的辦事員(CLERK)的詳細資料;

6、找出部門10中所有的經理(MANAGER),部門20中所有辦事員(CLERK),既不是經理又不是辦事員但其薪金大於或等於2000的所有員工的詳細資料;

7、找出收取獎金的員工的不同工作;

8、找出不收取獎金或者收取的獎金低於100的員工;

9、找出各月倒數第三天受僱的所有員工;

10、找出早於十三年前受僱的員工;

       如果要求年份,最準確的是使用總月數/13

11、以首字母大寫的方式顯示所有員工的姓名;

12、顯示正好爲5個字符的員工的姓名;

13、顯示不帶有“R”的員工姓名;     

14、顯示所有員工姓名的前三個字符;

15、顯示所有員工的姓名,用“a”替換所有的“A”;

17、顯示員工的詳細資料,按姓名排序;

18、顯示員工的姓名和受僱日期,根據其服務年限,將最老的員工排在最前面;

19、顯示所有員工的姓名、工作和薪金,按工作的降序排序,若工作相同則按薪金排序;

20、顯示所有員工姓名、加入公司的年份和月份,按受僱日期所在月排序,若月份相同則將最早年份的員工排在最前面;

21、顯示在一個月爲30天的情況所有員工的日薪金,忽略餘數;

22、找出(任何年份的)2月受聘的所有員工;

23、對於每個員工,顯示其加入公司的天數;

24、顯示姓名字段的任何位置包含“A”的所有員工的姓名;

25、以年月日的方式顯示所有員工的服務年限;


答案:

基本SQL語句練習

以下SQL語句 我只將關鍵字段大寫了

1、選擇部門30中的所有員工;

要查的是所有員工

範圍限定的是部門30

SQL> select * from emp where deptno = 30;

      

2、列出所有辦事員(CLERK)的姓名,編號和部門編號;

要查的是姓名,編號和部門編號

範圍限定的是辦事員

SQL> select empno,ename,deptno from emp where job='CLERK';

      

3、找出獎金高於薪金的員工;

要查的是員工

範圍限定的是獎金高於薪金

SQL> select * from emp where comm>sal;

 

4、找出獎金高於薪金的60%的員工;

要查的是員工

範圍限定的是獎金高於薪金60%

SQL> select * from emp where comm>(sal*0.6);

 

5、找出部門10中的所有經理(MANAGER)和部門20中所有的辦事員(CLERK)的詳細資料;

要查的是所有資料

範圍限定的是部門10中的所有經理 部門20中所有的辦事員

注意:經理與辦事員字段要大寫,查詢的關係是or

SQL>select * from emp

where (deptno=10 and job='MANAGER') or (deptno=20 and job='CLERK');

 

6、找出部門10中所有的經理(MANAGER),部門20中所有辦事員(CLERK),既不是經理又不是辦事員但其薪金大於或等於2000的所有員工的詳細資料;

要查的是所有資料,範圍限定的是

部門10中的所有經理

部門20中所有的辦事員

既不是經理又不是辦事員但其薪金大於或等於2000

select * from emp

where (deptno=10 and job='MANAGER')

or (deptno=20 and job='CLERK')

or ((Job!='MANAGER' and job!='CLERK') and sal > =2000);

第三個條件也可以用IN來進行範圍限定 根據題中的要求 使用not in

(job not in ('MANAGER','CLERK') and sal > =2000)

             

7、找出收取獎金的員工的不同工作;

要查的是工作,

範圍限定的是

收取獎金的員工

SQL> select job from emp where comm is not null;

SQL> select job from emp where not comm is null;

用distinct來刪除重複項

SQL> select distinct job from emp where not comm is null;

 

8、找出不收取獎金或者收取的獎金低於100的員工;

要查的是員工(詳細資料),

範圍限定的是

不收取獎金  comm爲null

收取的獎金低於100

SQL> select * from emp where comm is null or comm <100;

 

9、找出各月倒數第三天受僱的所有員工;

要查的是員工(詳細資料),

範圍限定的是

各月倒數第三天受僱

思路:

       先取出僱傭日期當月的最後一天 (將其天數取出來) 然後減去2 如果是受僱的天數,那麼就符合條件。

步驟:

  1. 先取出僱傭日期的day1
  2. 取出僱傭月份的最後一天day2
  3. 用大日期減小日期 day2-day1 如果等於2就輸出
select last_day(hiredate) from emp;

SQL> select hiredate,to_char(hiredate,'yyyy-mm-dd'),to_char(hiredate,'  dd')day1 from emp;


SQL>select last_day(hiredate),

to_char(last_day(hiredate),'yyyy-mm-dd'),

to_char(last_day(hiredate),'  dd')day2

from emp;

 

爲了計算所以只保留需要的數據字段 day1 day2

select to_char(hiredate,'  dd')day1 from emp;

select to_char(last_day(hiredate),'  dd')day2 from emp;

最終:

select * from emp where ((to_char(last_day(hiredate),'  dd') - to_char(hiredate,'  dd')) =2);

 

檢查:可見第五個人確實是當月的倒數第三天 當月有30天 倒數第三天就是28天

另外一種做法是不用取出來具體的天數 直接用當月最後一天減去2 如果等於hiredate那就符合條件

SQL> SELECT * FROM EMP WHERE LAST_DAY(HIREDATE)-2=HIREDATE;

10、找出早於十三年前受僱的員工;

思路:

       首先將受僱的年份取出來,然後用現在的年份受僱的年份   >13 就打印

select to_char(hiredate,'yyyy')year1 from emp;

select to_char(sysdate,' yyyy')year2 from emp;

 

最終:

select * from emp where (to_char(sysdate,' yyyy') - to_char(hiredate,'yyyy')) > 13 ;

 

做法2:

SQL> SELECT * FROM EMP WHERE MONTHS_BETWEEN(SYSDATE,HIREDATE)/12>13;

能用函數儘量函數,因爲十分便捷

 

11、以首字母大寫的方式顯示所有員工的姓名;

SQL> select initcap(ename) from emp;

 

12、顯示正好爲5個字符的員工的姓名;

SQL> select ename from emp where length(ename)=5;

13、顯示不帶有“R”的員工姓名;

SQL> select ename from emp where ename not like '%R%';

      

14、顯示所有員工姓名的前三個字符;

按照的是正常的數數,而不是從0開始,從0開始數的是程序員

SQL> select ename,substr(ename,0,3) from emp;

SQL> select ename,substr(ename,1,3) from emp;

      

15、顯示所有員工的姓名,用“a”替換所有的“A”;

SQL> select replace(ename,'A','a') from emp;

      

17、顯示員工的詳細資料,按姓名排序;

排序默認用的是升序

SQL> select * from emp order by ename;

SQL> select * from emp order by ename asc;

      

18、顯示員工的姓名和受僱日期,根據其服務年限,將最老的員工排在最前面;

注意:這裏要按照升序排序,因爲要將時間上小的排在前面(年長的)

SQL> select ename,hiredate from emp order by hiredate asc;

 

19、顯示所有員工的姓名、工作和薪金,按工作的降序排序,若工作相同則按薪金排序;

SQL> select ename,job,sal from emp order by job desc,sal asc;

      

20、顯示所有員工姓名、加入公司的年份和月份,按受僱日期所在月排序,若月份相同則將最早年份的員工排在最前面;

 

由於出現了年份與月份,則應該先進行拆分

月份按照默認的升序排序,最早年份的員工則按照升序

總結:

一旦出現與年份相關的,想要年長的排在前面,那麼就按照升序排序

       select  ename,to_char(hiredate,'yyyy') year,to_char(hiredate,'   mm') month from emp

order by month,year asc;

             

21、顯示在一個月爲30天的情況所有員工的日薪金,忽略餘數;

要查的是日薪金(忽略餘數)利用別名(日薪金)

範圍限定的是 一個月爲30天

思路:

       用sal/30 並忽略餘數,別名替代算出來的日薪金

select ename,trunc(sal/30)day_sal from emp;

 

22、找出(任何年份的)2月受聘的所有員工;

要查的是員工

範圍限定的是2月受聘的

思路:

       利用to_char轉換函數取出月份 減去02 如果等於0 就打印

 

select ename from emp where ((to_char(hiredate,' mm') -02)=00);

如果需要對所有信息都打印,那麼就用*

select * from emp where ((to_char(hiredate,' mm') -02)=00);

檢查:可見只有這兩個人的受僱月份就是2月

 

23、對於每個員工,顯示其加入公司的天數;

要查的是員工與僱傭的天數

思路:

       用當前日期減去僱傭的日期就是加入的天數

 

       select ename,hiredate,sysdate-hiredate from emp;

 

24、顯示姓名字段的任何位置包含“A”的所有員工的姓名;

       思路:

       採用模糊查詢

SQL> select ename from emp where ename like '%A%';

 

25、以年月日的方式顯示所有員工的服務年限;

第一步:求出每個僱員的僱傭年數:被僱傭的總月數/12=年數

select  ename,hiredate,trunc(months_between(sysdate,hiredate)/12)toatl_year from emp;

 

第二步:求出月數,以上計算之中被忽略的小數點都是月份,所以直接取餘即可。

select ename,hiredate,

trunc(months_between(sysdate,hiredate)/12)toatl_year,

trunc(mod(months_between(sysdate,hiredate),12))total_month

from emp;

 

第三步:求出天數,最準確的做法是在不超過30天的範圍內計算;

當前時間用sysdate取出,僱傭時期用hiredate取出,可是兩者中間的差距太大,所以肯定的會有誤差,那麼就必須想辦法將hiredate日期提升到與sysdate差距在30天的範圍之內,

有兩個函數;

       MONTHS_BETWEEN();求出兩個日期間的月數。

       ADD_MONTHS():在一個日期上加入指定的月之後的日期。

如果說hiredate+與今天相距的月數=一個新的日期,而且這個新的日期肯定和sysdate相距不超過30天。

                                  

       1987入職 +月數(month between(sys date,hiredate  )

                                  

       SQL> select ename,hiredate,

              trunc(months_between(sysdate,hiredate)/12)year,

              trunc(mod(months_between(sysdate,hiredate),12))month,

              trunc(sysdate-add_months(hiredate,months_between(sysdate,hiredate))) day

              from emp;    

 

      

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章