目錄
1.SQL語言簡介
SQL語句通常用於完成一些數據庫的操作任務,具有增加、刪除、修改、數據定義與控制等完整的數據庫操作功能。
特點:
1.集合性。在高層的數據結構上工作,而不對單個記錄進行操作,可操作記錄集。所有SQL語句接收集合作爲輸入,返回集合作爲輸出。
2.統一性。SQL爲許多任務提供了統一的命令,方便學習和使用。數據庫的操作任務通常包括以下幾方面:
查詢數據;
在表中插入、修改和刪除記錄;
建立、修改和刪除數據對象;
控制對數據和數據對象的讀寫;
保證數據庫一致性和完整性。
3.高度非過程化。SQL是一個非過程化的語言,沒有循環結構和函數定義等功能,只提“做什麼”,不管“怎麼做”。
4.語言簡單,易學易用。整個SQL語句只用9個命令動詞即可實現對數據庫及數據的查詢和管理。如下表:
SQL的功能 | 命令動詞 |
---|---|
數據定義 | CREATE,DROP,ALTER |
數據操縱 | SELECT,INSERT,UPDATE,DELETE |
數據控制 | GRANT,REVOKE |
5.以同一種語法結構提供兩種使用方式。第一種是交互式應答使用,即用戶在終端命令提示符下輸入SQL命令時數據庫服務器可以立即執行;第二種是通過預編譯SQL進行執行,即把SQL命令嵌入到應用程序中執行。
6.是所有關係數據庫的公共語言。所有主要的關係數據庫管理系統都支持,所以是可移植的。
分類:
1.數據查詢語言(DQL)
用於檢索數據庫中的數據,主要是select
2.數據操縱語言(DML)
用於改變數據庫中的數據,主要是insert,update,delete
3.事務控制語言(TCL)
用於維護數據的一致性,主要是commit,rollback,savepoint(設置保存點)
4.數據定義語言(DDL)
用於建立、修改和刪除數據庫對象。主要是CREATE,DROP,ALTER。例如ALTER TABLE 修改表結構。
5.數據控制語言(DCL)
用於執行權限授予和權限收回操作。GRANT用於給用戶或角色授予權限,REVOKE用於收回用戶或角色所具有的權限。
編寫規則
SQL關鍵字不區分大小寫;
對象名和列名不區分大小寫;
字符值區分大小寫;
SQL語句較長和分行顯示,輸入完畢要以分號作爲結束符。
2.用戶模式
某個用戶所創建的數據庫對象(數據表,索引,視圖等)都屬於該用戶模式,便於管理。
模式與模式對象
模式是一個數據庫對象的集合。模式爲一個數據庫用戶所有,並且名稱相同。
模式對象是由用戶創建的邏輯結構,用以存儲或引用數據,如表,索引,約束,視圖,同義詞,過程,程序包等。
模式擁有模式對象。
示例模式scott
該模式是Oracle提供的一個典型的示例模式,演示了一個很簡單的公司人力資源管理的數據結構。
先查看scott用戶是否存在:
alter user scott account unlock;
當scott用戶不存在,
我們就需要在$ORACLE_HOME目錄下尋找scott.sql文件,找到之後在命令行中執行文件:@ + 找到的文件位置
如果scott.sql文件都不存在(如上圖),還可以執行urlsampl.sql文件創建scott用戶,這個文件也位於$ORACLE_HOME/rdbms/admin文件夾下(執行之後會自動斷開oracle的連接):
然後就可以了。
用默認密碼"tiger"登錄scott用戶。
或者:
查看scott用戶擁有的數據表:
3.檢索數據
檢索數據我之前已經進行過整理,在這就簡單總結一下,查漏補缺。
這是以前寫的:數據庫常用sql語句總結。
主要有7個子句:
group by 子句用於對檢索結果進行分組顯示
having子句用於從使用group by子句分組後的查詢結果中篩選數據行。
簡單查詢
1.檢索所有的列,select * from 表名
2.檢索指定的列,select col_name1,col_name2
3.帶有表達式的select子句,select sal*(1+0.1)
4.爲列指定別名,select empno as "員工編號",可去掉as
5.顯示不重複記錄,select distinct job from emp
6.處理null值,select ename,sal,comm,sal+nvl(comm,0) from emp
如果comm列存在數值,返回其原有數值,若爲null,返回0
7.連接字符串,||或concat,select ename||'的工作是'||job from emp;
篩選查詢
1.比較查詢,=,!或<>,>,<,>=,<=
特殊:
A運算符ANY(B),A與B中任何一個元素進行比較,只要有一個比較值爲true,返回數據行
A運算符ALL(B),A與B中所有元素進行比較,只有與所有元素的比較值爲true,才返回數據行
2.使用特殊關鍵字篩選
LIKE:字符串模糊查詢。通配符:%:代表0個或多個字符;_:只能代表一個字符。
IN:測試一個數據值是否匹配一組目標值中的一個。IN(目標值1,目標值2,...)。NOT IN表示不在某一組目標值中。
BETWEEN:某一數據值是否位於兩個給定的值之間。BETWEEN...AND... ,NOT BETWEEN...AND...
IS NULL,不用=號判斷null
3.邏輯篩選
AND OR NOT
分組查詢
GROUP BY
1.單列分組
group by 經常和聚集函數一起使用,可以實現對查詢結果中每一組數據進行分類統計。
常用統計函數:AVG ,COUNT ,MAX ,MIN ,SUM
例如:在emp表中,對工資記錄進行分組,並計算平均工資等。
select job,avg(sal),sum(sal),max(sal),count(job)
from emp
group by job;
2.多列分組
select deptno,job,avg(sal),sum(sal),max(sal)
from emp
group by deptno,job;
3.使用order by子句改變分組排序結果
4.使用having子句限制分組結果
類似於where,但是having可以包含聚合函數
select job,avg(sal),sum(sal),max(sal),count(job)
from emp
group by job
having avg(sal)>2000;
5.使用ROLLUP和CUBE操作符
group by只能生成簡單的數據統計結果,這兩個操作符可以生成橫向小計,縱向小計和總計等
直接看例子:
ROLLUP:
CUBE:
GROUPING函數,查看是否使用了特定列(用到了多個列或沒有用到任何列):
複合列:引用複合列時需要用括號括住相關列。使用複合列可以略過ROLLUP和CUBE操作符的某些統計結果。
---------------------
GROUPING SETS 操作符:爲了顯示多個分組的統計結果,就用該操作符合並分組結果:
排序查詢
ORDER BY
ASC 升序 ;DESC 降序
ORDER BY 語句和GROUP BY 語句都位於FROM語句之後,如果使用了GROUP BY 子句,則該子句一定是SQL語句的最後一個子句。
1.單列排序,不多說
2.多列排序
當以多列進行排序時,首先按照第一列進行排序,當第一列存在相同數據時,再以第二列進行排序,以此類推。
在此查詢語句中,首先按照部門號排序,在同一個部門中,按照工地從高到低排序。
多表關聯查詢
1.表的別名
多表關聯時如果存在同名的列,需要用表名來限定列的引用,而爲了避免語句冗長,就可以設定簡短的表別名。
FROM子句最先執行,然後纔是WHERE子句和SELECT子句,所以在FROM子句中指定表的別名後,其他所有子句都能使用。
別名一經定義,在整個查詢語句中就只能使用別名不能使用表名,只在所定義的查詢語句中有效。
2.內連接
返回的查詢結果中只包含符合查詢條件和連接條件的行。消除了與另一個表中的任何行不匹配的行。
FROM table_name1 [INNER] JOIN table_name2
ON join_condition;
3.外連接
除了返回所有匹配的行,還會返回一部分或全部不匹配的行,主要取決於外連接的種類。
左外連接 LEFT JOIN
右外連接 RIGHT JOIN
完全外連接 FULL JOIN
外連接不只列出與連接條件匹配的行,還能夠列出左表(左外連接時)、右表(右外連接時)或兩個表(完全外連接時)中所有符合搜索條件的數據行。
當使用“(+)”操作符執行外連接時,應該講該操作符放在顯示較少行(完全滿足連接條件)的一端。
select e.empno,e.ename,e.job,d.deptno,d.dname
from emp e right join dept d
on e.deptno=d.deptno;
還可以這麼寫:
select e.empno,e.ename,e.job,d.deptno,d.dname
from emp e , dept d
where e.deptno(+)=d.deptno;
如果WHERE子句中包含多個條件,則必須在所有條件中都包含“(+)”操作符。
4.自連接
就是自己連接自己,主要用在自參考表上顯示上下級關係或者層次關係。自參考表指的是在同一張表的不同列之間具有參照關係或主從關係的表。
例如,emp表包含empno(僱員號)和mgr(管理員號),兩者之間就具有參照關係。
5.交叉連接
不需要任何連接條件,使用CROSS JOIN 關鍵字實現。
執行結果是一個笛卡爾積,非常冗餘,但可以通過WHERE子句過濾出有用的記錄信息。
4.Oracle常用系統函數
字符類函數
ASCII(c) | 返回一個字符的ASCII碼, CHR(i) 返回給出ASCII碼值所對應的字符 |
CONCAT(s1,s2) | 將字符串s2連接到字符串s1的後面 |
INITCAP(s) | 將字符串s的每個單詞的第一個字母大寫,其他字母小寫 |
INSTR(s1,s2[,i][,j]) | 返回字符串s2在字符串s1中第j次出現的位置,搜索從s1的第i個字符開始。未找到返回0,i爲負從右往左搜索 |
LENGTH(s) | 返回字符串s的長度 |
LOWER(s)和UPPER(s) | 返回字符串s的小寫形式和大寫形式 |
LTRIM(s1,s2)、RTRIM(s1,s2)、TRIM(s1,s2) | 分別用來刪除字符串s1左邊、右邊、兩邊的字符串s2。若不指定s2,表示去除相應地方的空格 |
REPLACE(s1,s2[,s3]) | 使用s3字符串替換出現在s1字符串中的所有s2字符串,並返回替換後的新字符串,s3默認值爲空 |
SUBSTR(s,i[,j]) | 從字符串s的第i個位置開始截取長度爲j的子字符串,省略參數j,則直接截取到尾部 |
數字類函數
ABS(n) | 返回n的絕對值 |
CEIL(n) | 返回大於或等於n的最小整數 |
COS(n) | 返回n的餘弦值,n爲弧度 |
EXP(n) | 返回e的n次冪 |
FLORR(n) | 返回小於或等於n的最大整數 |
LOG(n1,n2) |
返回以n1爲底n2的對數 |
MOD(n1,n2) | 返回n1除以n2的餘數 |
POWER(n1,n2) | 返回n1的n2次方 |
ROUND(n1,n2) | 返回舍入小數點右邊n2位的n1的值,n2默認值爲0 |
SIGN(n) | 若n爲負數,返回-1,n爲正數返回1,n爲0返回0 |
SIN(n) | 返回n的正弦值,n爲弧度 |
SORT(n) | 返回n的平方根,n爲弧度 |
TRUNC(n1,n2) | 返回結尾到n2位小數的n1的值,n2默認值爲0 |
舉個例子:
日期和時間類函數
ADD_MONTHS(d,i) | 返回日期d加上i個月之後的結果,i爲整數 |
LAST_DAY(d) | 返回包含日期d月份的最後一天 |
MONTHS_BETWEEN(d1,d2) | 返回d1和d2之間的數目(通俗點就是d1減d2有幾個月) |
NEW_TIME(d1,t1,t2) |
當t1和d1相同時,返回t2。d1時日期數據類型,t1和t2是字符串 |
SYSDATE() | 返回系統當前的日期 |
轉換類函數
CHARTORWIDA | 將字符串s轉換爲RWID數據類型 |
CONVERT(s,aset[,best]) | 將字符串s由best字符集轉換爲aset字符集 |
ROWIDTOCHAR() | 將ROWID數據類型轉換爲CHAR類型 |
TO_CHAR(x[,format]) | 將表達式轉換爲字符串,format表示字符串格式 |
TO_DATE(s[,format[lan]]) | 將字符串s轉換爲date類型,format表示字符串格式,lan表示所使用的語言 |
TO_NUMBER(s[,format[lan]]) | 將返回字符串s代表的數字,format表示字符串格式,lan表示所使用的語言 |
聚合類函數
AVG(x[DISTINCT|ALL]) | 計算選擇列表項的平均值,列表項目可以是一個列或多個列的表達式 |
COUNT(x[DISTINCT|ALL]) | 返回查詢結果中的記錄數 |
MAX(x[DISTINCT|ALL]) | 返回選擇列表項目中的最大數,列表項目可以是一個列或多個列的表達式 |
MIN(x[DISTINCT|ALL]) | 返回選擇列表項目中的最小數,列表項目可以是一個列或多個列的表達式 |
SUM(x[DISTINCT|ALL]) | 返回選擇列表項目的數值總和,列表項目可以是一個列或多個列的表達式 |
VARIANCE(x[DISTINCT|ALL]) | 返回選擇列表項目的統計方差,列表項目可以是一個列或多個列的表達式 |
STDDEV(x[DISTINCT|ALL]) | 返回選擇列表項目的標準偏差,列表項目可以是一個列或多個列的表達式 |
5.子查詢的用法
在執行數據操作(增刪查改)的過程中,如果某個操作需要依賴於另外一個SELECT語句的查詢結果,那麼就可以把SELECT語句嵌入到該操作語句中,這樣就形成了一個子查詢。
什麼是子查詢
子查詢是在SQL語句內的另外一條SELECT語句,也稱爲內查詢。在SELECT、INSERT、UPDATE、DELETE等命令中允許是一個表達式的地方都可以包含子查詢,子查詢甚至可以包含在另外一個子查詢中。
比如,在SCOTT模式下,在emp表中查詢部門名稱(ename)爲“RESEARCH”的員工信息。代碼如下:
對以上代碼進行分析,emp表是不存在dname字段(部門名稱)的,但存在deptno字段(部門代碼);dname字段原本存在於dept表中,dept表中也存在deptno字段,所以deptno爲兩個表之間的關聯字段。所以本示例的需求也可以通過多表關聯查詢來實現。代碼如下:
子查詢的使用更加靈活、功能更強大並且易於理解;
多表關聯查詢的查詢效率更高。(因爲子查詢語句需要檢索一遍數據,然後判斷外查詢語句的條件是否滿足,滿足則添加到結果集,不滿足則繼續判斷下一行數據)
單行子查詢
單行子查詢是指返回一行數據的子查詢語句。
當在where子句中引用單行子查詢時,可以使用單行比較運算符(=、>、<、>=、<=、<>)。
在emp表中,查出既不是最高工資,也不是最低工資的員工信息。
多行子查詢
多行子查詢是指返回多行數據的子查詢語句。
當在where子句中使用多行子查詢時,必須使用多行比較符(IN、ANY、ALL)。
使用IN運算符
外查詢與子查詢結果進行匹配,只要有一個匹配成功,則返回當前檢索的記錄
在emp表中,查詢不是銷售部門的員工信息
使用ANY運算符
必須與單行操作符結合使用,並且返回行只要匹配子查詢的任何一個結果即可。
在emp表中,查詢工資大於10號部門的任意一個員工工資的其他部門的員工信息。
使用ALL運算符
必須與單行操作符結合使用,並且返回行必須匹配所有子查詢結果。
在emp表中,查詢工資大於30號部門的所有員工工資的員工信息。
關聯子查詢
上述兩種子查詢中,內查詢和外查詢是分開執行的,外查詢僅僅是使用了內查詢的結果。在一些特殊需求的子查詢中,內查詢的執行需要藉助於外查詢,而外查詢的執行又離不開內查詢的執行。這時,內外查詢是相互關聯的,這種子查詢就被稱爲關聯子查詢。
在emp表中,檢索工資大於同職位的平均工資的員工信息。
在上面的查詢語句中,內查詢使用關聯子查詢計算每個職位的平均工資,而關聯子查詢必須知道職位的名稱,爲此外查詢就使用f.job字段值爲內查詢提供職位名稱。如果外層查詢正在檢索的數據行的工資高於平均工資,則該行的員工信息會顯示出來。
6.操作數據庫
插入數據(INSERT語句)
單條插入數據:
a.使用列列表
insert into dept(deptno,dname,loc)
values(88,'design','beijing');
b.不使用列列表
insert into jobs values('PRO','程序員',5000,10000);
c.使用特定格式
insert into emp(empno,ename,job,hiredate)
values(1356,'MARY','CLERK',to_date(1983-10-20,'YYYY-MM-DD'));
d.使用DEFAULT提供數據
insert into dept values(60,'MARKET',DEFAULT);
如果列不存在默認值則爲NULL
e.使用替代變量插入數據
accept no prompt '請輸入僱員號:'
accept name prompt '請輸入僱員名:'
accept title prompt '請輸入僱員崗位:'
accept d_no prompt '請輸入部門號:'
insert into emp(empno,ename,job,hiredate,deptno)
values(&no,'&name','&title',SYSDATE,&d_no);
批量插入數據:
insert into jobs_temp
select * from jobs
where jobs.max_salary >10000;
即使用INSERT語句和SELECT語句的組合可以一次性插入多條記錄。
注意,兩個語句對應的列之間,數據類型必須是兼容的,即select語句返回的數據必須滿足insert into表中的約束。
更新數據(UPDATE語句)
更新單列數據:
update emp
set sal = 2460
where ename='SCOTT';
更新多列數據:
update emp
set sal = sal*1.2
where job='SALESMAN';
列之間用逗號隔開。
更新日期列數據:
update emp
set hiredate = TO_DATE('1984/01/01','YYYY/MM/DD')
where empno=7788;
使用DEFAULT選項更新數據:
update emp
set job = DEFAULT
where ename='SCOTT';
如果列不存在默認值則爲NULL。
使用子查詢更新數據:
同INSERT語句一樣,UPDATE語句也可以與SELECT語句組合使用。
update emp
set sal = (select avg(sal)
from emp where job = 'MANAGER')
where sal < 2000;
刪除數據(DELETE語句和TRUNCATE語句)
delete語句:刪除數據庫中的所有記錄和指定範圍的記錄(通過WHERE子句進行限制)。
delete from jobs where job_id='PRO';
delete from emp;
TRUNCATE語句:刪除表中的所有記錄。
比DELETE快得多,因爲它不會產生回滾記錄,不能用ROLLBACK語句撤銷。
truncate table jobs_temp;
--------------------------------------------
歡迎關注公衆號“編程江湖”,可以領取Java、Python、微信小程序等相關學習資料和項目源碼,還能查看技術文章。