GJM :SQL Server中經常使用的SQL語句

原帖地址: http://www.cnblogs.com/rainman/archive/2013/05/04/3060428.html#m1html

一、概述

名詞

笛卡爾積、主鍵、外鍵post

數據完整性

  • 實體完整性:主屬性不能爲空值,例如選課表中學號和課程號不能爲空
  • 參照完整性:表中的外鍵取值爲空或參照表中的主鍵
  • 用戶定義完整性:取值範圍或非空限制,例如:性別(男女),年齡(0-130)

  

錶鏈接

  • 天然鏈接:與等值鏈接(a.id=b.id)相比,鏈接後的表只有一列id,而不是兩列(a.id和b.id)。
  • 半鏈接:與等值鏈接(a.id=b.id)相比,鏈接後的表只有A表的列,被B表「屢次匹配」列會顯示爲一行。
  • 左外鏈接:left join
  • 右外鏈接:right join
  • 全外鏈接:full join
  • 全內鏈接:inner join

SQL語言的構成

  • DDL語言:數據定義,定義基本表、視圖、索引;
  • DML語言:數據操縱,查詢、增長、修改、刪除
  • DCL語言:權限

  

二、查詢概述

查詢包括:單表查詢、鏈接查詢、帶有exists的相關子查詢、集合操做四中。select...from經常使用語句執行過程server

select…            ⑤    投影
from…              ①    table→內存
where…             ②    選取元組
group…             ③    分組
having…            ④    選擇分組
[{union|…}         ⑥    查徇結果的集      合運算
select…  ]         ①~⑤
order by…          ⑦    排序輸出

三、單表查詢

group by 只有出如今group by子句中的屬性,纔可出如今select子句中。htm

用order by子句對查詢結果按照一個或多個列的值進行升/降排列輸出,升序爲ASC;降序爲desc,空值將做爲最大值排序blog

having 與 where的區別排序

  • where 決定哪些元組被選擇參加運算,做用於關係中的元組
  • having 決定哪些分組符合要求,做用於分組

四、鏈接查詢

鏈接查詢包括:多表鏈接查詢、單錶鏈接查詢(自鏈接)、外鏈接查詢、嵌套查詢4種索引

鏈接條件一內存

[表名1.] 列名1 比較運算符  [表名2.]列名2

鏈接條件二get

[表名1.]列名1  between [表名2.]列名2 and [表名2.]列名3

鏈接條件中的列名稱爲鏈接字段,對應的鏈接字段應是可比的。io

執行過程:採用表掃描的方法,在表1中找到第一個元組,而後從頭開始掃描表2,查找到知足條件的元組即進行串接並存入結果表中;再繼續掃描表2,依次類推,直到表2末尾。再從表1中取第二個元組,重複上述的操做,直到表1中的元組所有處理完畢。

4.1 單錶鏈接(自鏈接)

用表別名把一個表定義爲兩個不一樣的表進行鏈接。

例:查找至少選修了2號和4號課程的學生的學號

select FIRST.sno
from SC as FIRST, SC as SECOND 
where FIRST.Sno=SECOND.Sno and FIRST.cno='s2' and SECOND.cno='4'

4.2 外鏈接查詢

外鏈接查詢包括:Left join、right join、full join

4.3 嵌套查詢

  • 在select … from … where語句結構的where子句中可嵌入一個select語句塊
  • 其上層查詢稱爲外層查詢或父查詢,其下層查詢稱爲內層查詢或子查詢
  • SQL語言容許使用多重嵌套查詢
  • 在子查詢中不容許使用order by子句
  • 嵌套查詢的實現通常是從裏到外,即先進行子查詢,再把其結果用於父查詢做爲條件
4.3.1 返回單個值的子查詢

例:求與「劉力」同一個系的學生名,年齡

方法一:
select Sname, Sage 
from student 
where Sdept = (select sdept from student where  Sname = "劉力");

方法二:
select FIRST.Sname, FIRST.Sage 
from Student FIRST, Student SECOND
where FIRST.Sdept = SECOND.Sdept AND SECOND.Sname = "劉力";
4.3.2 返回一組值的子查詢

例:求選修「C6」課程且成績超過90分的學生

方法一:
select * from 
student 
where sno IN (select sno from SC where Cno="C6" AND Grade>90);

方法二(鏈接查詢 ):
select student.*		
from student,SC
where Student.Sno=SC.Sno AND Cno="C6" AND Grade>90;

例:求比計算機系中某一學生年齡小的其餘系的學生

方法一:
select * 
from student 
where
    sdept!="CS" AND  
    sage < ANY (select Sage from Student where Sdept="CS");
	
方法二:
select  *
from Student
where   
   Sdept!=’CS’ AND  
   Sage < (select MAX(Sage) from Student where Sdept="CS");
4.3.3 多重子查詢

例:求D01部門中工資與國貿系中任意職工相同的職工姓名和工資

表結構:
Teacher(tno, tname, salary, dno)
Department(dno, dname)

查詢語句:
select Tname,Salary
from Teacher
where 
    Dno = "D01" AND 
    salary IN(
        select salary from  teacher
        where Dno =(select DNO from department where  Dname="國貿")
    );

例:求工資介於「張三」與「裏司」兩個之間的職工

select *
from teacher
where
    Salary >= (select MIN(Salary) from teacher where Tname IN ("張三", "裏司")) AND  
    Salary <= (select MAX(Salary) from teacher where Tname IN ("張三", "裏司");
4.3.4 在from語句中使用子查詢,對查詢結果定義表名及列名

例:求平均成績超過80分的學號及平均成績

select Sno, avg_G
from (select Sno, avg(Grade) from SC group by Sno) AS RA(Sno, avg_G)
where avg_G > 80;

AS RA(Sno, avg_G),爲查詢做爲定義表名(RA)和列名(Sno, avg_G)

五、帶有exists的相關子查詢

  • 不相關子查詢:子查詢的查詢條件不依賴於父查詢的稱爲不相關子查詢。
  • 相關子查詢:子查詢的查詢條件依賴於外層父查詢的某個屬性值的稱爲相關子查詢,帶exists 的子查詢就是相關子查詢
  • exists表示存在量詞,帶有exists的子查詢不返回任何記錄的數據,只返回邏輯值「True」 或「False」

例:求全部選修了「C1」課程的學生名。

不相關子查詢:    
select Sname from student where sno IN ( select sno from SC where Cno = "C1" );
 
相關子查詢
select Sname from student
where exists (select * from SC where student.sno=SC.sno AND Cno = "C1" );

相關子查詢執行過程:先在外層查詢中取student表的第一個元組(記錄),用該記錄的相關的屬性值(在內層where子句中給定的)處理內層查詢,若外層的where子句返回‘TRUE’值,則此元組送入結果的表中。而後再取下一個元組;重複上述過程直到外層表的記錄所有遍歷一次爲止。

  • 不關心子查詢的具體內容,所以用 select *
  • exists + 子查詢用來判斷該子查詢是否返回元組
  • 當子查詢的結果集非空時,exists 爲「True」;當子查詢的結果集爲空時,exists爲「False」。
  • not exists :若子查詢結果爲空,返回「TRUE」值,不然返回「FALSE」

例:查詢選修了全部課程的學生的姓名(續)

select Sname
from student
where not exists (
    select * 
    from Course
    where not exists (
        select * from SC where 
        student.sno=SC.sno AND Course.Cno=SC.Cno
    )
);

例:查詢至少選修了S1所選的所有課程的學生名

select Sname
from student
where not exists(
    select *
    from SC SCX			
    where 
        SCX.sno="s1" AND 
        not exists (
            select *
            from SC SCY
            where student.sno=SCY.sno AND SCX.Cno=SCY.Cno
        )
);

六、SQL的集合操做

  • 屬性個數必須一致、對應的類型必須一致
  • 屬性名能夠不一致, 最終結果集採用第一個結果的屬性名
  • 缺省爲自動去除重複元組,除非顯式說明ALL
  • order by放在整個語句的最後

6.1 「並」操做,例:查詢計算機系的學生或者年齡不大於19歲的學生,並按年齡倒排序。

select * from student where Sdept="CS"
UNION
select * from student where AGE <= 19
order by AGE desc

6.2 「交」操做,例:查詢計算機系的學生而且年齡不大於19歲的學生,並按年齡倒排序。

(select * from student where Sdept = "CS") 
INTERSECT
(select * from student where AGE <= 19)
order by AGE desc

6.3 「差」操做,例:查詢選修課程1但沒有選修課程2的學生。

select Sname, Sdept
from student
where sno IN (
    (select sno from SC where Cno="1")
    EXCEPT
    (select sno from SC where Cno="2")
) 

七、插入操做

格式:insert  into  表名[(列名1,…)]  values  (列值1,…)

插入一已知元組的所有列值

insert into student values("2003001", "陳冬", 18, "男", "電商", "管理學院", "徐州");

插入一已知元組的部分列值

insert into SC(Sno,Cno) values ("2003001", "C003");

插入子查詢的結果

例:設關係S_G(Sno,avg_G),把平均成績大於80的男生的學號及平均成績存入S_G中
insert into S_G(sno,avg_G) (
    select sno, avg(GRADE)
    from SC
    where Sno IN (select Sno from Student where SEX="男")
    group  by  Sno
    having  avg(GRADE) > 80
);

八、刪除操做

格式: 
delete from 表名 [where 條件];
  • 只能對整個元組操做,不能只刪除某些屬性上的值
  • 只能對一個關係(表)起做用,若要從多個關係(表)中刪除元組,則必須對每一個關係分別執行刪除命令

九、修改操做

update語句一次只能操做一個表。

格式1:
update 表名 [別名]
set 列名 = 表達式, ...
[where 條件];

格式2:
update 表名 [別名]
set (列名, ...) = (子查詢)
[where 條件];

例:工種爲SALESMEN的職工的工資改成工種平均工資的110%

update EMPLOYEE
set Salary = (select 1.1 * avg(Salary) from EMPLOYEE where JOB="SALESMEN")
where JOB="SALESMEN"; 

例:將全部學生的年齡增長1歲

update student set Sage=Sage+1; 

十、數據定義

建立課程表

create table SC (
    sno CHAR(6) not null,
    Cno CHAR(6) not null,
    Grade smallint default null
)
primary key (sno,Cno)
foreign key (sno) references student(sno)
foreign key (Cno) references Course(Cno)
check (Grade between 0 AND 100);

經常使用的索引:惟一索引和聚簇索引

惟一索引
  • 對於已含重複值的屬性列不能建UNIQUE索引
  • 對某個列創建UNIQUE索引後,插入新記錄時DBMS會自動檢查新記錄在該列上是否取了重複值。這至關於增長了一個UNIQUE約束
create UNIQUE INDEX  Stusno ON Student(Sno ASC);
聚簇索引

創建聚簇索引後,基表中數據也須要按指定的聚簇屬性值的升序或降序存放。也即聚簇索引的索引項順序與表中記錄的物理順序一致

create CLUSTER INDEX Stusname ON Student(Sname);

在Student表的Sname(姓名)列上創建一個聚簇索引,並且Student表中的記錄將按照Sname值的升序存放。Sql server中的表示方式create clustered index。某些DMBS不支持聚簇索引,因此用前必定要查使用說明。

  • 在一個基本表上最多隻能創建一個聚簇索引
  • 聚簇索引的用途:對於某些類型的查詢,能夠提升查詢效率
  • 聚簇索引的適用範圍:不多對基表進行增刪操做;不多對其中的變長列進行修改操做
刪除索引

刪除索引時,系統會從數據字典中刪去有關該索引的描述。

DROP INDEX [表名.]<索引名>;

例:刪除Student表的Stusname索引

DROP INDEX Student.Stusname;

十一、視圖

例:創建電商系學生的視圖

create view ec_student
as 
select sno, sname, age from student where dept="ec"

刪除視圖

DROP VIEW <視圖名>

一個視圖被刪除後,由此視圖導出的其餘視圖也將失效,用戶應該使用DROP VIEW語句將他們一一刪除

相關文章
相關標籤/搜索