1. 程式人生 > >Sql常用查詢操作

Sql常用查詢操作

1.查詢語句模板:

需要注意的是:

  1.  FROM 才是 SQL 語句執行的第一步,並非 SELECT 。
  2. SELETC 是在WHERE語句執行之後執行的,所以不能再WHERE語句後使用SELECT中設定的別名
  3. WHERE是對分組前進行的過濾,HAVING是對分組後進行過濾。

2.sql中的 與 或 非

與--and  或--or 非--not  注意的是 :and 優先順序高於 or   A and B or C and D  最後執行or

3.設定別名:

select sal*12 as "年薪" from  表名 t ;

  sa "年薪" 給 列設定別名 , t 是給表設定別名

4.查詢空值

select * from emp where comm is null (is not null)

5.模糊查詢:

%(萬用字元)表示任意長度的字元 ,表示一個字元。 例如以S開頭的 任意結束  (S%)

select 欄位名 from 表名 where 欄位名 like '%s%' ; 

6.分組:

通過性別不同分組查資料:

select sex, avg(age) as 平均年齡 from user group by sex;

注意:

 

  1. 使用分組後select 後面只能寫分組條件(group by後面的值)或者組函式
  2. 分組函式  count  min  max avg sum   
  3. 要篩選結果 可以先使用where 再用group by 或者先用group by 再用having
  4. group by 執行過程如下:

7.單行函式: 

1)數字函式 

--四捨五入 ROUND(input[,n]) n表示小數位如果n被忽略則無小數位
SELECT ROUND(12.111) FROM dual;
SELECT ROUND(12.111,1) FROM dual;
SELECT ROUND(12.164,1) FROM dual;
--擷取數字 TRUNC (input[,n]) 將數字值擷取,n代表擷取的小數位,如果n被忽略則預設0
SELECT TRUNC(12.113) FROM dual;
SELECT TRUNC(12.113,2) FROM dual;
--返回m除於n的餘數 MOD(m,n)
SELECT MOD(3,2) FROM dual

2)字元函式

select * from emp;
--轉換為大寫
SELECT UPPER(e.ename) FROM emp e;
--轉換為小寫
SELECT LOWER(e.ename) FROM emp e;
--首字母轉換為大寫
SELECT INITCAP(ename) FROM emp
--連線第一個字元到第二個字元等價於“||”
SELECT CONCAT(ename,empno) EMPINFO FROM emp
SELECT ename ||' ' || empno EMPINFO FROM emp 
--獲取字串中指定的字元,SUBSTR(input,m,[n]) 從m位置開始,取n個字元長度,如果n被忽略,則取到字串結尾處
SELECT SUBSTR(ename,1,3) FROM emp
SELECT SUBSTR(ename,1) FROM emp
--返回字串的字元數
SELECT ename,LENGTH(ename) as "str_length" FROM emp
--返回字元值中查詢字串char的數字位置,m作為查詢的開始,n代表第n次發現,m,n預設值為1,及預設是從開始位置查詢,報告第一個查詢到的位置INSTR(input,char[,m][.n])
SELECT ename,INSTR(ename,'A') as "第一次出現a的位置" FROM (SELECT UPPER(ename) as ename  FROM emp )
--從字串中查詢字元char1,找到則替換為char2
SELECT REPLACE(ename,'A','哈哈') FROM emp
--左補全函式
SELECT LPAD('EMPNO',12,'*') FROM emp
--右補全函式
SELECT RPAD('EMPNO',12,'*')FROM emp

3)日期函式

/*
       ORACLE預設的日期格式是DD-MON-RR 如 17-JUN-13  PL/SQL格式為YYYY/MM/DD 如 2013/6/17
       1-12月 JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
       週一到週日 SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY
*/
--返回倆個日期之間的月數,返回的是數值型
SELECT MONTHS_BETWEEN('17-JUN-13','21-JAN-11') FROM dual;
SELECT MONTHS_BETWEEN('17-APR-2013','21-JUN-2011') FROM dual;
--1.檢視當前時間(SQL Server 使用 GETDATE()方法)
SELECT SYSDATE FROM dual;
--2.計算在指定日期之後的下一個周char指定天的日期,char可以是一個表示星期的數或字串
 SELECT  NEXT_DAY(SYSDATE,'MONDAY') FROM dual;
 SELECT  NEXT_DAY(SYSDATE,2) FROM dual;
--3.新增n個日曆月後的日期
 SELECT ADD_MONTHS('17-JUN-13',3) FROM dual;
--4.計算包含指定日期所在月的最後一天日期
 SELECT LAST_DAY('17-JUN-13') FROM dual;
--5.四捨五入日期 日期1日到15日結果在當前月的第一天,16到31為下一月的最後一天 1月到6月為當年,7到12為下一年1月1日
 SELECT ROUND(SYSDATE) FROM dual;
 SELECT ROUND(SYSDATE,'MONTH') FROM dual;
 SELECT ROUND(SYSDATE,'YEAR') FROM dual;
--6.擷取日期
 SELECT TRUNC(SYSDATE) FROM dual;
 SELECT TRUNC(SYSDATE,'MONTH') FROM dual;
 SELECT TRUNC(SYSDATE,'YEAR') FROM dual;
--7.檢視僱員表中 員工編號為7876的員工截止至今工作了多少個周
SELECT e.empno ||' '||e.ename as "EmployeeInfo", ROUND((sysdate-e.hiredate)/7) as "workWeeks" FROM 
 emp e where e.empno='7876';
--8查詢受僱日期在1981年1月1日到1982年1月1日的僱員,要查的資訊包括僱員編號,已經僱傭的月數,三個月試用期結束的日期,
--提交入職資料的日期(僱傭日下一週週一),首月結算薪資日期(受僱月最後一天)

SELECT empno as "員工編號",MONTHS_BETWEEN(SYSDATE,e.hiredate) as 已僱月數,ADD_MONTHS(e.hiredate,3) as 試用期結束,
NEXT_DAY(e.hiredate,'MONDAY') as 提交入職資料,LAST_DAY(e.hiredate) as 結算薪資  FROM emp e;

4)轉換函式

/*
  在ORACLE中對於直接賦值,ORACLE能自動將VARCHAR2或CHAR轉換為NUMBER或者DATE型別,也能將NUMBER和DATE自動轉換為VAARCHAR2型別
*/
--日期轉換為CHAR TO_CHAR(date[,'fmt']) 格式模板必須放在單引號裡,並且大小寫敏感
SELECT TO_CHAR(SYSDATE,'YYYY/MM/DD,HH24-MI-SS') FROM dual;
SELECT TO_CHAR(SYSDATE,'fmYYYY/MM/DD,HH24-MI-SS') FROM dual;--fm刪除填補的空或者前導的0
SELECT TO_CHAR(SYSDATE,'Y,YYY/MM/DD,HH24-MI-SS') FROM dual;
SELECT TO_CHAR(SYSDATE,'YY/MM/DD,Q,HH24-MI-SS') FROM dual;
SELECT TO_CHAR(SYSDATE,'YEAR/MM/DD,HH24-MI-SS') FROM dual;

--數字使用TO_CHAR
SELECT TO_CHAR(1234,'$999999') FROM dual;--前面有兩個空格   $1234
SELECT TO_CHAR(1234,'L999999') FROM dual; --
SELECT TO_CHAR(1234,'9999.99') FROM dual;-- 1234.00
SELECT TO_CHAR(1234,'999,999') FROM dual;--   1,234
SELECT TO_CHAR(-1234,'999999MI') FROM dual;--負數右邊顯示負號  1234-
SELECT TO_CHAR(-1234,'999999PR') FROM dual;--負數加上括號    <1234>
SELECT TO_CHAR(-1234,'999999EEEE') FROM dual;--科學計數法 -1E+03

--字串使用TO_NUMBER 
SELECT TO_NUMBER('1234','9999') FROM dual; 
SELECT TO_NUMBER('1234','999') FROM dual; --報錯
SELECT TO_NUMBER(TO_CHAR(SYSDATE,'YYYY'),'9999') FROM dual; 
--字元轉換為日期TO_DATE
SELECT TO_DATE('17-JUN-18') FROM dual;
SELECT TO_DATE('Jan 03,2016','fxMon DD,YYYY') FROM dual;--fx精確匹配
SELECT TO_DATE('Jan 3,2016','Mon DD,YYYY') FROM dual;
SELECT TO_DATE('Jan 03,2016','Mon DD,YYYY ') FROM dual;
SELECT TO_DATE('Jan 03,2016','Mon DD;YYYY') FROM dual;
--查詢僱傭日期為1980/12/17的僱員,顯示僱員名字和僱傭日期
SELECT ename,e.hiredate FROM emp e where e.hiredate=TO_DATE('17-DEC-1980','DD-MON-YYYY');
SELECT ename,e.hiredate FROM emp e where e.hiredate=TO_DATE('1980-12-17','YYYY-MM-DD');
SELECT ename,e.hiredate FROM emp e where TO_CHAR(e.hiredate,'DD-MM-YYYY')='17-12-1980';

 5)通用函式:

 -------非空判斷
 ---NVL函式 相當於IF語句    NVL(可能為空的列名,value)用一個指定的值value替換一個NULL 
 SELECT comm from emp
 SELECT NVL(comm,0) from emp     
 ---NVL2函式 相當於IF ELSE語句 nvl(列名,vlaue,value) 檢查第一個引數,如果該引數的值不為空,則該函式返回第二個引數的值,否則返回第三個引數的值
 SELECT e.empno,e.ename,NVL2(comm,1,0) FROM emp e--不為空返回1為空返回0
 -------複雜的邏輯判斷 case when then 
 SELECT (CASE e.comm 
        WHEN 300 THEN 8888
        WHEN 500 THEN 6666 
          ELSE 0 
            END) AS COMM FROM emp e
 

6)ROW_NUMBER() OVER 

row_number()從1開始,為每一條分組記錄返回一個數字;

例1:ROW_NUMBER() OVER (ORDER BY xlh DESC) 是先把xlh列降序,再為降序以後的每條xlh記錄返回一個序號。 

例2:row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根據COL1分組,在分組內部根據 COL2排序,而此函式計算的值就表示每組內部排序後的順序編號(組內連續的唯一的)

8.多表查詢--子查詢

1)適用場景:查詢的結果集中只涉及一個表的列(子查詢的結果集只能有一列)

2)單行子查詢:(內部查詢結果集只有一條記錄)   可以用到的符號= 、!=、  > 、 <、<>

select * from emp where deptno=(select  from dept)

3)多行子查詢:(內部查詢結果集有多條記錄)可以用到的符號(in,any,all)

select * from emp where salary  in (100,200,300)

9.多表查詢--表連線

1)適用場景:查詢結果集中涉及到兩個表中的列的時候

2內連線內連線,也被稱為自然連線,只有兩個表相匹配的行才能在結果集中出現。返回的結果集選取了兩個表中所有相匹配的資料,捨棄了不匹配的資料。

等值內連線:等值內連線inner join 返回兩個表中主外來鍵匹配的資料(兩個表中不為空的數大的記錄數)

select * from emp e inner join dept d on e.deptno=d.deptno 

select * from emp e,dept d where e.deptno=d.deptno   簡化上面的寫法

非等值內連線(不是用=進行連線的)

select  e.ename ,s.grade from emp e inner join salgrade s on e.sal between s.losal  and  s. hisal

3)外連線:

外連線不僅包含符合連線條件的行,還包含左表(左連線時)、右表(右連線時)或兩個邊接表(全外連線)中的所有資料行。

SQL外連線共有三種類型:左外連線(關鍵字為LEFT OUTER JOIN)、右外連線(關鍵字為RIGHT OUTER JOIN)和全外連線(關鍵字為FULL OUTER JOIN)。

外連線的用法和內連線一樣,只是將INNER JOIN關鍵字替換為相應的外連線關鍵字即可。

左連線(返回內連線的結果,同時返回左表為匹配的行)

select * from emp e left outer join dept d on e.deptno=d.deptno                        Oracle資料庫可以在從表加(+)

右連線(返回內連線的結果,同時返回右表沒有匹配的行)

select *  from emp e right outer  join dept d on e.deptno=d.deptno

全連線(返回所有資訊包括內連線和左右連線的值)

select * from emp e full outer join dept d on e.depton=d.depton

10.集合操作符:

1)並集 UNION(合併兩個或多個 SELECT 語句的結果集。)

SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2

union all 與 union區別:

union 去除重複的資料 union all 不去除重複的資料

union 會對結果集進行排序,union all不會排序,sql優化時用union all 避免不必要的排序操作

2)交集INTERSECT(預設去除重複的資料)

合併兩個SELECT語句,但只從第一個SELECT語句返回完全相同於第二個SELECT語句結果的所有行。這意味著INTERSECT是由兩個SELECT語句返回相同的行(唯一)。

3)差集MINUS(預設去除重複的資料)

MINUS 指令是運用在兩個 SQL 語句上。它先找出第一個 SQL 語句所產生的結果,然後看這些結果有沒有在第二個 SQL 語句的結果中。如果有的話,那這一筆資料就被去除,而不會在最後的結果中出現。如果第二個 SQL 語句所產生的結果並沒有存在於第一個 SQL 語句所產生的結果內,那這筆資料就被拋棄。

A minus B就意味著將結果集A去除結果集B中所包含的所有記錄後的結果,即在A中存在,而在B中不存在的記錄

如有問題,多多指正!