當前位置:首頁 » 編程語言 » sql語句高級

sql語句高級

發布時間: 2023-03-01 11:06:01

sql 語句大全

1、說明:創建資料庫
CREATE DATABASE database-name
2、說明:刪除資料庫
drop database dbname
3、說明:備份sql server
--- 創建 備份數據的 device
USE master
EXEC sp_admpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
--- 開始 備份
BACKUP DATABASE pubs TO testBack
4、說明:創建新表
create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
根據已有的表創建新表:
A:create table tab_new like tab_old (使用舊表創建新表)
B:create table tab_new as select col1,col2… from tab_old definition only
5、說明:刪除新表
drop table tabname
6、說明:增加一個列
Alter table tabname add column col type
註:列增加後將不能刪除。DB2中列加上後數據類型也不能改變,唯一能改變的是增加varchar類型的長度。
7、說明:添加主鍵: Alter table tabname add primary key(col)
說明:刪除主鍵: Alter table tabname drop primary key(col)
8、說明:創建索引:create [unique] index idxname on tabname(col….)
刪除索引:drop index idxname
註:索引是不可更改的,想更改必須刪除重新建。
9、說明:創建視圖:create view viewname as select statement
刪除視圖:drop view viewname
10、說明:幾個簡單的基本的sql語句
選擇:select * from table1 where 范圍
插入:insert into table1(field1,field2) values(value1,value2)
刪除:delete from table1 where 范圍
更新:update table1 set field1=value1 where 范圍
查找:select * from table1 where field1 like 』%value1%』 ---like的語法很精妙,查資料!
排序:select * from table1 order by field1,field2 [desc]
總數:select count as totalcount from table1
求和:select sum(field1) as sumvalue from table1
平均:select avg(field1) as avgvalue from table1
最大:select max(field1) as maxvalue from table1
最小:select min(field1) as minvalue from table1
11、說明:幾個高級查詢運算詞
A: UNION 運算符
UNION 運算符通過組合其他兩個結果表(例如 TABLE1 和 TABLE2)並消去表中任何重復行而派生出一個結果表。當 ALL 隨 UNION一起使用時(即 UNION ALL),不消除重復行。兩種情況下,派生表的每一行不是來自 TABLE1 就是來自 TABLE2。
B: EXCEPT 運算符
EXCEPT運算符通過包括所有在 TABLE1 中但不在 TABLE2 中的行並消除所有重復行而派生出一個結果表。當 ALL 隨 EXCEPT 一起使用時 (EXCEPT ALL),不消除重復行。
C: INTERSECT 運算符
INTERSECT運算符通過只包括 TABLE1 和 TABLE2 中都有的行並消除所有重復行而派生出一個結果表。當 ALL隨 INTERSECT 一起使用時 (INTERSECT ALL),不消除重復行。
註:使用運算詞的幾個查詢結果行必須是一致的。
12、說明:使用外連接
A、left (outer) join:
左外連接(左連接):結果集幾包括連接表的匹配行,也包括左連接表的所有行。
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
B:right (outer) join:
右外連接(右連接):結果集既包括連接表的匹配連接行,也包括右連接表的所有行。
C:full/cross (outer) join:
全外連接:不僅包括符號連接表的匹配行,還包括兩個連接表中的所有記錄。
12、分組:Group by:
一張表,一旦分組 完成後,查詢後只能得到組相關的信息。
組相關的信息:(統計信息) count,sum,max,min,avg 分組的標准)
在SQLServer中分組時:不能以text,ntext,image類型的欄位作為分組依據
在selecte統計函數中的欄位,不能和普通的欄位放在一起;
13、對資料庫進行操作:
分離資料庫: sp_detach_db;附加資料庫:sp_attach_db 後接表明,附加需要完整的路徑名
14.如何修改資料庫的名稱:
sp_renamedb 'old_name', 'new_name'

㈡ 搜集SQL常用的操作語句

結構化查詢語言(Structured Query Language)簡稱SQL(發音:/ˈes kjuː ˈel/ "S-Q-L"),是一種特殊目的的編程語言,是一種資料庫查詢和程序設計語言,用於存取數據以及查詢、更新和管理關系資料庫系統;同時也是資料庫腳本文件的擴展名。

一、插入(復制)表數據

1、INSERT INTO 語句:

(1)插入新的一行數

[sql] view plain ;

INSERT INTO Persons VALUES ('Gates', 'Bill', 'Xuanwumen 10', 'Beijing');

(2)在指定的列中插入數據

[sql] view plain ;

INSERT INTO Persons (LastName, Address) VALUES ('Wilson', 'Champs-Elysees');

2、SQL SELECT INTO 語句可用於創建表的備份復件

(1)在建表時復制所有數據

[sql] view plain ;

create table userinfo_new as select * from userinfo;

(2)在建表時復制部分數據

[sql] view plain ;

create table userinfo_new1 as select id,username from userinfo;

(3)在添加時復制所有數據

[sql] view plain ;

insert into userinfo_new select * from userinfo;

(4)在添加時復制部分數據

[sql] view plain ;

insert into userinfo_new(id,username) select id,username from userinfo;

二、修改表數據

Update 語句

(1)無條件更新

[sql] view plain ;

update userinfo set userpwd='111',email='[email protected]';

(2)有條件更新

[sql] view plain ;

update userinfo set userpwd='123456' where username='xxx';

三、刪除表數據

1、DELETE 語句

(1)無條件刪除

[sql]view plain;

daletefromuserinfo;

(2)有條件刪除

[sql]view plain;

='yyy';

四、查詢表數據

1、SELECT 語句:

(1)查詢所有欄位

[sql] view plain ;

select * from users;

(2)查詢指定欄位

[sql] view plain ;

select username,salary from users;

2、SELECT DISTINCT 語句

從 Company" 列中僅選取唯一不同的值,需要使用 SELECT DISTINCT 語句:

[sql] view plain ;

SELECT DISTINCT Company FROM Orders;

㈢ 列舉一些sql高級查詢語句

1.集合操作
學習oracle中集合操作的有關語句,掌握union,union all,minus,interest的使用,能夠描述結合運算,並且能夠將多個查詢組合到一個查詢中去,能夠控制行返回的順序。
包含集合運算的查詢稱為復合查詢。見表格1-1
表1-1
Operator Returns content
UNION 由每個查詢選擇的所有不重復的行 並集不包含重復值
UNION ALL 由每個查詢選擇的所有的行,包括所有重復的行 完全並集包含重復值
INTERSECT 由每個查詢選擇的所有不重復的相交行 交集
MINUS 在第一個查詢中,不在後面查詢中,並且結果行不重復 差集

所有的集合運算與等號的優先順序相同,如果SQL語句包含多個集合運算並且沒有圓括弧明確地指定另一個順序,Oracle伺服器將以從左到右的順序計算。你應該使用圓括弧來明確地指定帶另外的集合運算的INTERSECT (相交) 運算查詢中的賦值順序。
Union all 效率一般比union高。
1.1.union和union all
UNION(聯合)運算
UNION運算返回所有由任一查詢選擇的行。用UNION運算從多表返回所有行,但除去任何重復的行。
原則 :

􀂃?被選擇的列數和列的數據類型必須是與所有用在查詢中的SELECT語句一致。列的名字不必相同。
􀂃?聯合運算在所有被選擇的列上進行。
􀂃?在做重復檢查的時候不忽略空(NULL)值。
􀂃?IN運算有比UNION運算高的優先順序。
􀂃?在默認情況下,輸出以SELECT子句的第一列的升序排序。

全聯合(UNION ALL)運算
用全聯合運算從多個查詢中返回所有行。
原則

􀂃?和聯合不同,重復的行不被過濾,並且默認情況下輸出不排序。
􀂃?不能使用DISTINCT關鍵字。
使用:
Select statement union | union all Select statement;

1.2.intersect交集操作
相交運算
用相交運算返回多個查詢中所有的公共行。 無重復行。
原則

􀂃?在查詢中被 SELECT 語句選擇的列數和數據類型必須與在查詢中所使用的所有的 SELTCT 語句中的一樣,但列的名字不必一樣。
􀂃?相交的表的倒序排序不改變結果。
􀂃?相交不忽略空值。
使用:
Select statement intersect all Select statement;

1.3. minus差集操作
相減運算
用相減運算返回由第一個查詢返回的行,那些行不出現在第二個查詢中 (第一個SELECT語句減第二個SELECT語句)。
原則

􀂃?在查詢中被SELECT語句選擇的列數和數據類型必須與在查詢中所使用的所有的SELTCT語句中的一樣,但列的名字不必一樣。
􀂃?對於MINUS運算,在WHERE子句中所有的列都必須在SELECT子句中。

集合運算的原則
?在兩個SELECT列表中的表達式必須在數目上和數據類型上相匹配
?可以用圓括弧改變執行的順序
?ORDER BY子句:–只能出現在語句的最後–從第一個SELECT語句接收列名、別名,或者位置記號

註:?除了UNION ALL,重復行自動被清除
?在結果中的列名是第一個查詢中出現的列名
?除了UNION ALL,默認情況下按升序順序輸出
2.exists和not exists的使用
2.1. exists的使用
Exists用於只能用於子查詢,可以替代in,若匹配到結果,則退出內部查詢,並將條件標志為true,傳回全部結果資料,in不管匹配到匹配不到都全部匹配完畢,使用exists可以將子查詢結果定為常量,不影響查詢效果,而且效率高。如查詢所有銷售部門員工的姓名,對比如下:
IN is often better if the results of the subquery are very small
When you write a query using the IN clause, you're telling the rule-based optimizer that you want the inner query to drive the outer query.
When you write EXISTS in a where clause, you're telling the optimizer that you want the outer query to be run first, using each value to fetch a value from the inner query.
In many cases, EXISTS is better because it requires you to specify a join condition, which can invoke an INDEX scan. However, IN is often better if the results of the subquery are very small. You usually want to run the query that returns the smaller set of results first.

In和exists對比:
若子查詢結果集比較小,優先使用in,若外層查詢比子查詢小,優先使用exists。因為若用in,則oracle會優先查詢子查詢,然後匹配外層查詢,若使用exists,則oracle會優先查詢外層表,然後再與內層表匹配。最優化匹配原則,拿最小記錄匹配大記錄。
使用in
select last_name, title
from s_emp
where dept_id in
(select id
from s_dept
where name='Sales');

使用exists
select last_name,title
from s_emp e
where exists
(select 'x' --把查詢結果定為constant,提高效率
from s_dept s where s.id=e.dept_id and s.name='Sales');
2.2 not exists的使用
與exists 含義相反,也在子查詢中使用,用於替代not in。其他一樣。如查詢不在銷售部的員工姓名
select last_name,title
from s_emp e
where not exists
(select 'x' --把查詢結果定為constant,提高效率
from s_dept s where s.id=e.dept_id and s.name='Sales');
3.with子句
9i新增語法
1.使用with子句可以讓子查詢重用相同的with查詢塊,通過select調用,一般在with查詢用到多次情況下。

2.with子句的返回結果存到用戶的臨時表空間中,只做一次查詢,提高效率。

3.有多個查詢的時候,第1個用with,後面的不用with,並且用逗號隔開。

5.最後一個with子句與下面的查詢之間不能有逗號,只通過右括弧分割,查詢必須用括弧括起來

6.如果定義了with子句,而在查詢中不使用,那麼會報ora-32035錯誤:未引用在with子句中定義的查詢名。(至少一個with查詢的name未被引用,解決方法是移除未被引用的with查詢)

7.前面的with子句定義的查詢在後面的with子句中可以使用。
With子句目的是為了重用查詢。

語法:
With alias_name as (select1), --as和select中的括弧都不能省略
alias_name2 as (select2),--後面的沒有with,逗號分割

alias_namen as (select n) –與下面的查詢之間沒有逗號
Select ….
如查詢銷售部門員工的姓名:
--with clause
with a as
(select id from s_dept where name='Sales' order by id)
select last_name,title
from s_emp where dept_id in (select * from a);--使用select查詢別名

使用with子句,可以在復雜的查詢中預先定義好一個結果集,然後在查詢中反復使用,不使用會報錯。而且with子句獲得的是一個臨時表,如果在查詢中使用,必須採用select from with查詢名,比如
With cnt as(select count(*) from table)
Select cnt+1 from al;
是錯誤的。必須是
With cnt as(select count(*) shumu from user_tables)
Select shumu+1 from cnt;
--直接引用with子查詢中的列別名。

一個with查詢的實例:
查詢出部門的總薪水大於所有部門平均總薪水的部門。部門表s_dept,員工表s_emp。
分析:做這個查詢,首先必須計算出所有部門的總薪水,然後計算出總薪水的平均薪水,再篩選出部門的總薪水大於所有部門總薪水平均薪水的部門。那麼第1步with查詢查出所有部門的總薪水,第2步用with從第1步獲得的結果表中查詢出平均薪水,最後利用這兩次的with查詢比較總薪水大於平均薪水的結果,如下:
with
--step1:查詢出部門名和部門的總薪水
dept_costs as(
select a.name,sum(b.salary) dept_total
from
s_dept a,s_emp b
where a.id=b.dept_id
group by a.name
),
--step2:利用上一個with查詢的結果,計算部門的平均總薪水
avg_costs as(
select sum(dept_total)/count(*) dept_avg
from dept_costs
)
--step3:從兩個with查詢中比較並且輸出查詢結果
select name,dept_total
from dept_costs
where
dept_total>
(
select dept_avg
from
avg_costs
)
order by name;

從上面的查詢可以看出,前面的with查詢的結果可以被後面的with查詢重用,並且對with查詢的結果列支持別名的使用,在最終查詢中必須要引用所有with查詢,否則會報錯ora-32035錯誤。

再如有這樣一個需求:一個查詢,如果查詢的結果行不滿足是10的倍數,則補空行,直到是查詢出的行數是10的倍數。例如:select * from trademark這個查詢。
with cnt as (select 10-mod(count(*),10) shumu from trademark) –查詢比10的倍數差幾個空行
select id,name
from trademark
union all --空行加進去
select null,null --補空行
from al connect by rownum<=(select shumu from cnt); --10個中connect by可以使用子查詢
10g之前的寫法
with cnt as (select 10-mod(count(*),10) shumu from trademark) –查詢比10的倍數差幾個空行
select id,name
from trademark
union all --空行加進去
select null,null --補空行
from all_objects where rownum<=(select shumu from cnt);--使用all_objects行比較多

4.merge into合並資料
語法:(其中as可以省略)
MERGE INTO table_name AS table_alias
USING (table|view|sub_query) AS alias
ON (join condition)
WHEN MATCHED THEN
UPDATE SET
col1 = col_val1,
col2 = col2_val
WHEN NOT MATCHED THEN
INSERT (column_list)—多個列以逗號分割 //可以不指定列
VALUES (column_values);

作用:將源數據(來源於實際的表,視圖,子查詢)更新或插入到指定的表中(必須實際存在),依賴於on條件,好處是避免了多個insert和update操作。Merge是一個目標性明確的操作符,不允許在一個merge語句中對相同的行insert或update操作。這個語法僅需要一次全表掃描就完成了全部工作,執行效率要高於INSERT+UPDATE。例子如下:

drop table t;
CREATE TABLE T AS SELECT ROWNUM ID, A.* from DBA_OBJECTS A;

drop table t1;
CREATE TABLE T1 AS
SELECT ROWNUM ID, OWNER, TABLE_NAME, CAST('TABLE' AS VARCHAR2(100)) OBJECT_TYPE
from DBA_TABLES;

select * from dba_objects;
select * from dba_tables;

MERGE INTO T1 USING T
ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME AND T.OBJECT_TYPE = T1.OBJECT_TYPE)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME, T.OBJECT_TYPE);--insert後面不寫表示插入全部列

MERGE INTO T1 USING T
ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME, T.OBJECT_TYPE);--常見錯誤,連接條件不能獲得穩定的行,可以使用下面的用子查詢

MERGE INTO T1
USING (SELECT OWNER, OBJECT_NAME, MAX(ID) ID from T GROUP BY OWNER, OBJECT_NAME) T
ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);

SELECT ID, OWNER, OBJECT_NAME, OBJECT_TYPE from T
MINUS
SELECT * from T1;

drop table subs;
create table subs(msid number(9),
ms_type char(1),
areacode number(3)
);

drop table acct;
create table acct(msid number(9),
bill_month number(6),
areacode number(3),
fee number(8,2) default 0.00);

insert into subs values(905310001,0,531);
insert into subs values(905320001,1,532);
insert into subs values(905330001,2,533);
commit;

merge into acct a --操作的表
using subs b on (a.msid=b.msid)--使用原始數據來源的表,並且制定條件,條件必須有括弧
when matched then
update set a.areacode=b.areacode--當匹配的時候,執行update操作,和直接update的語法不一樣,不需要制定表名
when not matched then--當不匹配的時候,執行insert操作,也不需要制定表名,若指定欄位插入,則在insert後用括弧標明,不指定是全部插入
insert(msid,bill_month,areacode) values(b.msid,'200702',b.areacode);

另外,MERGE語句的UPDATE不能修改用於連接的列,否則會報錯
select * from acct;
select * from subs;
--10g新特性,單個操作
merge into acct a
using subs b on(a.msid=b.msid)
when not matched then--只有單個not matched的時候,只做插入,不做更新,只有單個matched的時候,只做更新操作
insert(a.msid,a.bill_month,a.areacode) values(b.msid,'200702',b.areacode);

update acct set areacode=800 where msid=905320001;

delete from acct where areacode=533 or areacode=531;

insert into acct values(905320001,'200702',800,0.00);

--刪除重復行
delete from subs b where b.rowid<(
select max(a.rowid) from subs a where a.msid=b.msid and a.ms_type=b.ms_type and a.areacode=b.areacode);

--10g新特性,merge操作之後,只有匹配的update操作才可以,用delete where子句刪除目標表中滿足條件的行。
merge into acct a
using subs b on (a.msid=b.msid)
when MATCHED then
update set a.areacode=b.areacode
delete where (b.ms_type!=0)
when NOT MATCHED then
insert(msid,bill_month,areacode)
values(b.msid,'200702',b.areacode)
where b.ms_type=0;
--10g新特性,滿足條件的插入和更新
merge into acct a
using subs b on (a.msid=b.msid)
when MATCHED then
update set a.areacode=b.areacode
where b.ms_type=0
when NOT MATCHED then
insert(msid,bill_month,areacode)
values(b.msid,'200702',b.areacode)
where b.ms_type=0;

select * from subs where ms_type=0;

㈣ 高級查詢的sql語句該怎麼寫

高級查詢的sql語句該怎麼寫
select id,title,(select StyleName from NewsStyle where News.StyleId=NewsStyle.StyleId) as StyleName,(select TypeName from NewsType where News.TypeId=NewsType.TypeId) as TypeName from News

㈤ 請問sql高級查詢應該注意的是什麼怎樣才能寫出高效果的語句

不太明白你所說的高級查詢是高級到什麼程度,但給你一點建議,是一般SQL語句的優化原則
1、盡量少地使用表連接(JOIN語句),一般用的話都不要超過5個,考慮用臨時表代替JION語句;使用JION語句時,盡量不要使用OUTER
JOIN。
2、盡量少使用子查詢,即SELECT
XX1,XX2,(SELECT
XX
FROM
TT)
AS
XX3
FROM
TTT這類語句盡量少使用,
3、盡量少使用視圖嵌套,即視圖中盡量不要再查詢視圖,除非必要
4、LIKE語句中少使用前置的「%」,在數據量龐大的時候,前置的「%」對性能的影響很明顯的
5、WHERE子句裡面盡量少使用OR子句

㈥ SQL查詢語句

SQL查詢語句大全

SQL語句無論是種類還是數量都是繁多的,很多語句也是經常要用到的,SQL查詢語句就是一個典型的例子,無論是高級查詢還是低級查詢,SQL查詢語句的需求是最頻繁的。那麼SQL查詢語句有哪些?下面跟我一起來看看吧!

一、簡單查詢語句

1. 查看錶結構

SQL>DESC emp;

2. 查詢所有列

SQL>SELECT * FROM emp;

3. 查詢指定列

SQL>SELECT empmo, ename, mgr FROM emp;

SQL>SELECT DISTINCT mgr FROM emp; 只顯示結果不同的項

4. 查詢指定行

SQL>SELECT * FROM emp WHERE job='CLERK';

5. 使用算術表達式

SQL>SELECT ename, sal*13+nvl(comm,0) FROM emp;

nvl(comm,1)的意思是,如果comm中有值,則nvl(comm,1)=comm; comm中無值,則nvl(comm,1)=0。

SQL>SELECT ename, sal*13+nvl(comm,0) year_sal FROM emp; (year_sal為別名,可按別名排序)

SQL>SELECT * FROM emp WHERE hiredate>'01-1月-82';

6. 使用like操作符(%,_)

%表示一個或多個字元,_表示一個字元,[charlist]表示字元列中的任何單一字元,[^charlist]或者[!charlist]不在字元列中的任何單一字元。

SQL>SELECT * FROM emp WHERE ename like 'S__T%';

7. 在where條件中使用In

SQL>SELECT * FROM emp WHERE job IN ('CLERK','ANALYST');

8. 查詢欄位內容為空/非空的語句

SQL>SELECT * FROM emp WHERE mgr IS/IS NOT NULL;

9. 使用邏輯操作符號

SQL>SELECT * FROM emp WHERE (sal>500 or job='MANAGE') and ename like 'J%';

10. 將查詢結果按欄位的值進行排序

SQL>SELECT * FROM emp ORDER BY deptno, sal DESC; (按部門升序,並按薪酬降序)

二、復雜查詢

1. 數據分組(max,min,avg,sum,count)

SQL>SELECT MAX(sal),MIN(age),AVG(sal),SUM(sal) from emp;

SQL>SELECT * FROM emp where sal=(SELECT MAX(sal) from emp));

SQL>SELEC COUNT(*) FROM emp;

2. group by(用於對查詢結果的分組統計) 和 having子句(用於限制分組顯示結果)

SQL>SELECT deptno,MAX(sal),AVG(sal) FROM emp GROUP BY deptno;

SQL>SELECT deptno, job, AVG(sal),MIN(sal) FROM emp group by deptno,job having AVG(sal)<2000;

對於數據分組的總結:

a. 分組函數只能出現在選擇列表、having、order by子句中(不能出現在where中)

b. 如果select語句中同時包含有group by, having, order by,那麼它們的順序是group by, having, order by。

c. 在選擇列中如果有列、表達式和分組函數,那麼這些列和表達式必須出現在group by子句中,否則就是會出錯。

使用group by不是使用having的前提條件。

3. 多表查詢

SQL>SELECT e.name,e.sal,d.dname FROM emp e, dept d WHERE e.deptno=d.deptno order by d.deptno;

SQL>SELECT e.ename,e.sal,s.grade FROM emp e,salgrade s WHER e.sal BETWEEN s.losal AND s.hisal;

4. 自連接(指同一張表的連接查詢)

SQL>SELECT er.ename, ee.ename mgr_name from emp er, emp ee where er.mgr=ee.empno;

5. 子查詢(嵌入到其他sql語句中的select語句,也叫嵌套查詢)

5.1 單行子查詢

SQL>SELECT ename FROM emp WHERE deptno=(SELECT deptno FROM emp where ename='SMITH');查詢表中與smith同部門的人員名字。因為返回結果只有一行,所以用「=」連接子查詢語句

5.2 多行子查詢

SQL>SELECT ename,job,sal,deptno from emp WHERE job IN (SELECT DISTINCT job FROM emp WHERE deptno=10);查詢表中與部門號為10的工作相同的員工的姓名、工作、薪水、部門號。因為返回結果有多行,所以用「IN」連接子查詢語句。

in與exists的區別: exists() 後面的子查詢被稱做相關子查詢,它是不返回列表的值的。只是返回一個ture或false的結果,其運行方式是先運行主查詢一次,再去子查詢里查詢與其對 應的結果。如果是ture則輸出,反之則不輸出。再根據主查詢中的每一行去子查詢里去查詢。in()後面的子查詢,是返回結果集的,換句話說執行次序和 exists()不一樣。子查詢先產生結果集,然後主查詢再去結果集里去找符合要求的欄位列表去。符合要求的輸出,反之則不輸出。

5.3 使用ALL

SQL>SELECT ename,sal,deptno FROM emp WHERE sal> ALL (SELECT sal FROM emp WHERE deptno=30);或SQL>SELECT ename,sal,deptno FROM emp WHERE sal> (SELECT MAX(sal) FROM emp WHERE deptno=30);查詢工資比部門號為30號的所有員工工資都高的員工的姓名、薪水和部門號。以上兩個語句在功能上是一樣的,但執行效率上,函數會高 得多。

5.4 使用ANY

SQL>SELECT ename,sal,deptno FROM emp WHERE sal> ANY (SELECT sal FROM emp WHERE deptno=30);或SQL>SELECT ename,sal,deptno FROM emp WHERE sal> (SELECT MIN(sal) FROM emp WHERE deptno=30);查詢工資比部門號為30號的任意一個員工工資高(只要比某一員工工資高即可)的員工的姓名、薪水和部門號。以上兩個語句在功能上是 一樣的,但執行效率上,函數會高得多。

5.5 多列子查詢

SQL>SELECT * FROM emp WHERE (job, deptno)=(SELECT job, deptno FROM emp WHERE ename='SMITH');

5.6 在from子句中使用子查詢

SQL>SELECT emp.deptno,emp.ename,emp.sal,t_avgsal.avgsal FROM emp,(SELECT emp.deptno,avg(emp.sal) avgsal FROM emp GROUP BY emp.deptno) t_avgsal where emp.deptno=t_avgsal.deptno AND emp.sal>t_avgsal.avgsal ORDER BY emp.deptno;

5.7 分頁查詢

資料庫的每行數據都有一個對應的行號,稱為rownum.

SQL>SELECT a2.* FROM (SELECT a1.*, ROWNUM rn FROM (SELECT * FROM emp ORDER BY sal) a1 WHERE ROWNUM<=10) a2="" where="" rn="">=6;

指定查詢列、查詢結果排序等,都只需要修改最里層的子查詢即可。

5.8 用查詢結果創建新表

SQL>CREATE TABLE mytable (id,name,sal,job,deptno) AS SELECT empno,ename,sal,job,deptno FROM emp;

5.9 合並查詢(union 並集, intersect 交集, union all 並集+交集, minus差集)

SQL>SELECT ename, sal, job FROM emp WHERE sal>2500 UNION(INTERSECT/UNION ALL/MINUS) SELECT ename, sal, job FROM emp WHERE job='MANAGER';

合並查詢的執行效率遠高於and,or等邏輯查詢。

5.10 使用子查詢插入數據

SQL>CREATE TABLE myEmp(empID number(4), name varchar2(20), sal number(6), job varchar2(10), dept number(2)); 先建一張空表;

SQL>INSERT INTO myEmp(empID, name, sal, job, dept) SELECT empno, ename, sal, job, deptno FROM emp WHERE deptno=10; 再將emp表中部門號為10的數據插入到新表myEmp中,實現數據的批量查詢。

5.11 使用了查詢更新表中的數據

SQL>UPDATE emp SET(job, sal, comm)=(SELECT job, sal, comm FROM emp where ename='SMITH') WHERE ename='SCOTT';

簡介

SQL語言1974年由Boyce和Chamberlin提出,並首先在IBM公司研製的關系資料庫系統SystemR上實現。由於它具有功能豐富、使用方便靈活、語言簡潔易學等突出的優點,深受計算機工業界和計算機用戶的歡迎。1980年10月,經美國國家標准局(ANSI)的資料庫委員會X3H2批准,將SQL作為關系資料庫語言的美國標准,同年公布了標准SQL,此後不久,國際標准化組織(ISO)也作出了同樣的決定。

SQL從功能上可以分為3部分:數據定義、數據操縱和數據控制。

SQL的核心部分相當於關系代數,但又具有關系代數所沒有的許多特點,如聚集、資料庫更新等。它是一個綜合的、通用的、功能極強的關系資料庫語言。其特點是:

1、數據描述、操縱、控制等功能一體化。

2、兩種使用方式,統一的語法結構。SQL有兩種使用方式。一是聯機交互使用,這種方式下的SQL實際上是作為自含型語言使用的。另一種方式是嵌入到某種高級程序設計語言(如C語言等)中去使用。前一種方式適合於非計算機專業人員使用,後一種方式適合於專業計算機人員使用。盡管使用方式不向,但所用語言的語法結構基本上是一致的。

3、高度非過程化。SQL是一種第四代語言(4GL),用戶只需要提出「干什麼」,無須具體指明「怎麼干」,像存取路徑選擇和具體處理操作等均由系統自動完成。

4、語言簡潔,易學易用。盡管SQL的'功能很強,但語言十分簡潔,核心功能只用了9個動詞。SQL的語法接近英語口語,所以,用戶很容易學習和使用。

功能

SQL具有數據定義、數據操縱、和數據控制的功能。

1、SQL數據定義功能:能夠定義資料庫的三級模式結構,即外模式、全局模式和內模式結構。在SQL中,外模式又叫做視圖(View),全局模式簡稱模式(Schema),內模式由系統根據資料庫模式自動實現,一般無需用戶過問。

2、SQL數據操縱功能:包括對基本表和視圖的數據插入、刪除和修改,特別是具有很強的數據查詢功能。

3、SQL的數據控制功能:主要是對用戶的訪問許可權加以控制,以保證系統的安全性。

語句結構

結構化查詢語言包含6個部分:

1、數據查詢語言(DQL: Data Query Language):其語句,也稱為「數據檢索語句」,用以從表中獲得數據,確定數據怎樣在應用程序給出。保留字SELECT是DQL(也是所有SQL)用得最多的動詞,其他DQL常用的保留字有WHERE,ORDER BY,GROUP BY和HAVING。這些DQL保留字常與其它類型的SQL語句一起使用。

2、數據操作語言(DML:Data Manipulation Language):其語句包括動詞INSERT、UPDATE和DELETE。它們分別用於添加、修改和刪除。

3、事務控制語言(TCL):它的語句能確保被DML語句影響的表的所有行及時得以更新。包括COMMIT(提交)命令、SAVEPOINT(保存點)命令、ROLLBACK(回滾)命令。

4、數據控制語言(DCL):它的語句通過GRANT或REVOKE實現許可權控制,確定單個用戶和用戶組對資料庫對象的訪問。某些RDBMS可用GRANT或REVOKE控制對表單個列的訪問。

5、數據定義語言(DDL):其語句包括動詞CREATE,ALTER和DROP。在資料庫中創建新表或修改、刪除表(CREATE TABLE 或 DROP TABLE);為表加入索引等。

6、指針控制語言(CCL):它的語句,像DECLARE CURSOR,FETCH INTO和UPDATE WHERE CURRENT用於對一個或多個表單獨行的操作。

語言特點

SQL風格統一

SQL可以獨立完成資料庫生命周期中的全部活動,包括定義關系模式、錄入數據、建立資料庫、査詢、更新、維護、資料庫重構、資料庫安全性控制等一系列操作,這就為資料庫應用系統開發提供了良好的環境,在資料庫投入運行後,還可根據需要隨時逐步修改模式,且不影響資料庫的運行,從而使系統具有良好的可擴充性。

高度非過程化

非關系數據模型的數據操縱語言是面向過程的語言,用其完成用戶請求時,必須指定存取路徑。而用SQL進行數據操作,用戶只需提出「做什麼」,而不必指明「怎麼做」,因此用戶無須了解存取路徑,存取路徑的選擇以及SQL語句的操作過程由系統自動完成。這不但大大減輕了用戶負擔,而且有利於提高數據獨立性。

面向集合的操作方式

SQL採用集合操作方式,不僅查找結果可以是元組的集合,而且一次插入、刪除、更新操作的對象也可以是元組的集合。

以同一種語法結構提供兩種使用方式

SQL既是自含式語言,又是嵌入式語言。作為自含式語言,它能夠獨立地用於聯機交互的使用方式,用戶可以在終端鍵盤上直接輸入SQL命令對資料庫進行操作。作為嵌入式語言,SQL語句能夠嵌入到高級語言(如C、C#、JAVA)程序中,供程序員設計程序時使用。而在兩種不同的使用方式下,SQL的語法結構基本上是一致的。這種以統一的語法結構提供兩種不同的操作方式,為用戶提供了極大的靈活性與方便性。

語言簡潔,易學易用

SQL功能極強,但由於設計巧妙,語言十分簡潔,完成數據定義、數據操縱、數據控制的核心功能只用了9個動詞:CREATE、ALTER、DROP、SELECT、INSERT、UPDATE、DELETE、GRANT、REVOKE。且SQL語言語法簡單,接近英語口語,因此容易學習,也容易使用。

;

㈦ 如何寫出高性能SQL語句

優化SQL查詢:如何寫出高性能SQL語句
1、首先要搞明白什麼叫執行計劃?
執行計劃是資料庫根據SQL語句和相關表的統計信息作出的一個查詢方案,這個方案是由查詢優化器自動分析產生欀如一條SQL語句如果用來從一個10萬條記錄的表中查1條記錄,那查詢優化器會選擇「索引查找」方式,如果該表進行了歸檔,當前只剩下5000條記錄了,那查詢優化器就會改變方案,採用 「全表掃描」方式。

可見,執行計劃並不是固定的,它是「個性化的」。產生一個正確的「執行計劃」有兩點很重要:

(1) SQL語句是否清晰地告訴查詢優化器它想干什麼?

(2) 查詢優化器得到的資料庫統計信息是否是最新的、正確的?

2、統一SQL語句的寫法
對於以下兩句SQL語句,程序員認為是相同的,資料庫查詢優化器認為是不同的。

select * from al
select * From al

其實就是大小寫不同,查詢分析器就認為是兩句不同的SQL語句,必須進行兩次解析。生成2個執行計劃。
所以作為程序員,應該保證相同的查詢語句在任何地方都一致,多一個空格都不行!

3、不要把SQL語句寫得太復雜
我經常看到,從資料庫中捕捉到的一條SQL語句列印出來有2張A4紙這么長。一般來說這么復雜的語句通常都是有問題的。我拿著這2頁長的SQL語句去請教原作者,結果他說時間太長,他一時也看不懂了。可想而知,連原作者都有可能看糊塗的SQL語句,資料庫也一樣會看糊塗。

一般,將一個Select語句的結果作為子集,然後從該子集中再進行查詢,這種一層嵌套語句還是比較常見的,但是根據經驗,超過3層嵌套,查詢優化器就很容易給出錯誤的執行計劃。因為它被繞暈了。像這種類似人工智慧的東西,終究比人的分辨力要差些,如果人都看暈了,我可以保證資料庫也會暈的。

另外,執行計劃是可以被重用的,越簡單的SQL語句被重用的可能性越高。而復雜的SQL語句只要有一個字元發生變化就必須重新解析,然後再把這一大堆垃圾塞在內存里。可想而知,資料庫的效率會何等低下。

4、使用「臨時表」暫存中間結果
簡化SQL語句的重要方法就是採用臨時表暫存中間結果,但是,臨時表的好處遠遠不止這些,將臨時結果暫存在臨時表,後面的查詢就在tempdb中了,這可以避免程序中多次掃描主表,也大大減少了程序執行中「共享鎖」阻塞「更新鎖」,減少了阻塞,提高了並發性能。

5、 OLTP系統SQL語句必須採用綁定變數
select * from orderheader where changetime > 』2010-10-20 00:00:01′
select * from orderheader where changetime > 』2010-09-22 00:00:01′

以上兩句語句,查詢優化器認為是不同的SQL語句,需要解析兩次。
如果採用綁定變數

select * from orderheader where changetime > @chgtime

@chgtime變數可以傳入任何值,這樣大量的類似查詢可以重用該執行計劃了,這可以大大降低資料庫解析SQL語句的負擔。一次解析,多次重用,是提高資料庫效率的原則。

6、綁定變數窺測
事物都存在兩面性,綁定變數對大多數OLTP處理是適用的,但是也有例外。
比如在where條件中的欄位是「傾斜欄位」的時候。

「傾斜欄位」指該列中的絕大多數的值都是相同的,一張人口調查表,其中「民族」這列,90%以上都是漢族。那麼如果一個SQL語句要查詢30歲的漢族人口有多少,那「民族」這列必然要被放在where條件中。這個時候如果採用綁定變數@nation會存在很大問題。

試想如果@nation傳入的第一個值是「漢族」,那整個執行計劃必然會選擇表掃描。然後,第二個值傳入的是「布依族」,按理說「布依族」占的比例可能只有萬分之一,應該採用索引查找。但是,由於重用了第一次解析的「漢族」的那個執行計劃,那麼第二次也將採用表掃描方式。這個問題就是著名的「綁定變數窺測」,建議對於「傾斜欄位」不要採用綁定變數。

7、 只在必要的情況下才使用begin tran
SQL Server中一句SQL語句默認就是一個事務,在該語句執行完成後也是默認commit的。其實,這就是begin tran的一個最小化的形式,好比在每句語句開頭隱含了一個begin tran,結束時隱含了一個commit。

有些情況下,我們需要顯式聲明begin tran,比如做「插、刪、改」操作需要同時修改幾個表,要求要麼幾個表都修改成功,要麼都不成功。begin tran 可以起到這樣的作用,它可以把若干SQL語句套在一起執行,最後再一起commit。好處是保證了數據的一致性,但任何事情都不是完美無缺的。Begin tran付出的代價是在提交之前,所有SQL語句鎖住的資源都不能釋放,直到commit掉。

可見,如果Begin tran套住的SQL語句太多,那資料庫的性能就糟糕了。在該大事務提交之前,必然會阻塞別的語句,造成block很多。

Begin tran使用的原則是,在保證數據一致性的前提下,begin tran 套住的SQL語句越少越好!有些情況下可以採用觸發器同步數據,不一定要用begin tran。

8、一些SQL查詢語句應加上nolock
在SQL語句中加nolock是提高SQL Server並發性能的重要手段,在oracle中並不需要這樣做,因為oracle的結構更為合理,有undo表空間保存「數據前影」,該數據如果在修改中還未commit,那麼你讀到的是它修改之前的副本,該副本放在undo表空間中。這樣,oracle的讀、寫可以做到互不影響,這也是oracle 廣受稱贊的地方。

SQL Server 的讀、寫是會相互阻塞的,為了提高並發性能,對於一些查詢,可以加上nolock,這樣讀的時候可以允許寫,但缺點是可能讀到未提交的臟數據。
使用 nolock有3條原則。

(1) 查詢的結果用於「插、刪、改」的不能加nolock !

(2) 查詢的表屬於頻繁發生頁分裂的,慎用nolock !

(3) 使用臨時表一樣可以保存「數據前影」,起到類似oracle的undo表空間的功能,

能採用臨時表提高並發性能的,不要用nolock 。

9、聚集索引沒有建在表的順序欄位上,該表容易發生頁分裂
比如訂單表,有訂單編號orderid,也有客戶編號contactid,那麼聚集索引應該加在哪個欄位上呢?對於該表,訂單編號是順序添加的,如果在orderid上加聚集索引,新增的行都是添加在末尾,這樣不容易經常產生頁分裂。然而,由於大多數查詢都是根據客戶編號來查的,因此,將聚集索引加在contactid上才有意義。而contactid對於訂單表而言,並非順序欄位。

比如「張三」的「contactid」是001,那麼「張三」的訂單信息必須都放在這張表的第一個數據頁上,如果今天「張三」新下了一個訂單,那該訂單信息不能放在表的最後一頁,而是第一頁!如果第一頁放滿了呢?很抱歉,該表所有數據都要往後移動為這條記錄騰地方。

SQL Server的索引和Oracle的索引是不同的,SQL Server的聚集索引實際上是對表按照聚集索引欄位的順序進行了排序,相當於oracle的索引組織表。SQL Server的聚集索引就是表本身的一種組織形式,所以它的效率是非常高的。也正因為此,插入一條記錄,它的位置不是隨便放的,而是要按照順序放在該放的數據頁,如果那個數據頁沒有空間了,就引起了頁分裂。所以很顯然,聚集索引沒有建在表的順序欄位上,該表容易發生頁分裂。

曾經碰到過一個情況,一位哥們的某張表重建索引後,插入的效率大幅下降了。估計情況大概是這樣的。該表的聚集索引可能沒有建在表的順序欄位上,該表經常被歸檔,所以該表的數據是以一種稀疏狀態存在的。比如張三下過20張訂單,而最近3個月的訂單只有5張,歸檔策略是保留3個月數據,那麼張三過去的 15張訂單已經被歸檔,留下15個空位,可以在insert發生時重新被利用。在這種情況下由於有空位可以利用,就不會發生頁分裂。但是查詢性能會比較低,因為查詢時必須掃描那些沒有數據的空位。

重建聚集索引後情況改變了,因為重建聚集索引就是把表中的數據重新排列一遍,原來的空位沒有了,而頁的填充率又很高,插入數據經常要發生頁分裂,所以性能大幅下降。

對於聚集索引沒有建在順序欄位上的表,是否要給與比較低的頁填充率?是否要避免重建聚集索引?是一個值得考慮的問題!

10、加nolock後查詢經常發生頁分裂的表,容易產生跳讀或重復讀
加nolock後可以在「插、刪、改」的同時進行查詢,但是由於同時發生「插、刪、改」,在某些情況下,一旦該數據頁滿了,那麼頁分裂不可避免,而此時nolock的查詢正在發生,比如在第100頁已經讀過的記錄,可能會因為頁分裂而分到第101頁,這有可能使得nolock查詢在讀101頁時重復讀到該條數據,產生「重復讀」。同理,如果在100頁上的數據還沒被讀到就分到99頁去了,那nolock查詢有可能會漏過該記錄,產生「跳讀」。

上面提到的哥們,在加了nolock後一些操作出現報錯,估計有可能因為nolock查詢產生了重復讀,2條相同的記錄去插入別的表,當然會發生主鍵沖突。

11、使用like進行模糊查詢時應注意
有的時候會需要進行一些模糊查詢比如

select * from contact where username like 『%yue%』

關鍵詞%yue%,由於yue前面用到了「%」,因此該查詢必然走全表掃描,除非必要,否則不要在關鍵詞前加%,

12、數據類型的隱式轉換對查詢效率的影響
sql server2000的資料庫一的程序在提交sql語句的時候,沒有使用強類型提交這個欄位的值,由sql server 2000自動轉換數據類型,會導致傳入的參數與主鍵欄位類型不一致,這個時候sql server 2000可能就會使用全表掃描。Sql2005上沒有發現這種問題,但是還是應該注意一下。

13、SQL Server 表連接的三種方式
(1) Merge Join

(2) Nested Loop Join

(3) Hash Join

SQL Server 2000隻有一種join方式——Nested Loop Join,如果A結果集較小,那就默認作為外表,A中每條記錄都要去B中掃描一遍,實際掃過的行數相當於A結果集行數x B結果集行數。所以如果兩個結果集都很大,那Join的結果很糟糕。

SQL Server 2005新增了Merge Join,如果A表和B表的連接欄位正好是聚集索引所在欄位,那麼表的順序已經排好,只要兩邊拼上去就行了,這種join的開銷相當於A表的結果集行數加上B表的結果集行數,一個是加,一個是乘,可見merge join 的效果要比Nested Loop Join好多了。

如果連接的欄位上沒有索引,那SQL2000的效率是相當低的,而SQL2005提供了Hash join,相當於臨時給A,B表的結果集加上索引,因此SQL2005的效率比SQL2000有很大提高,我認為,這是一個重要的原因。

總結一下,在表連接時要注意以下幾點:

(1) 連接欄位盡量選擇聚集索引所在的欄位

(2) 仔細考慮where條件,盡量減小A、B表的結果集

(3) 如果很多join的連接欄位都缺少索引,而你還在用SQL Server 2000,趕緊升級吧。

熱點內容
ios登陸源碼 發布:2024-11-07 15:33:58 瀏覽:247
三d演算法 發布:2024-11-07 15:04:54 瀏覽:677
期貨指標公式源碼 發布:2024-11-07 14:53:05 瀏覽:316
sqlserver圖片路徑 發布:2024-11-07 14:37:56 瀏覽:67
磁羅經演算法 發布:2024-11-07 14:26:49 瀏覽:850
怎麼使用主機搭建伺服器 發布:2024-11-07 14:10:26 瀏覽:84
螞蟻礦機什麼配置 發布:2024-11-07 14:10:22 瀏覽:430
上海家譜資料庫 發布:2024-11-07 14:10:19 瀏覽:296
ibm伺服器如何修復系統 發布:2024-11-07 13:56:02 瀏覽:977
pythonarraylist 發布:2024-11-07 13:52:03 瀏覽:744