6_2數據查詢

還是使用6_1裏面創建的數據哦

use EMIS
go
--連接查詢
--一個查詢同時涉及兩個以上的表,就是連接查詢
--分類:交叉連接查詢、內連接查詢、外連接查詢
--多個表連接,需要利用連接條件來指定各列之間進行連接的關係。連接條件中的列必須具有已知的數據類型才能正確連接

--交叉連接(非限制連接)
--兩個表中的記錄的交叉乘積,結果集中的列爲兩個表屬性列的和,其連接的結果會產生一些毫無疑義的記錄,而且操作很耗時,該運算的實際意義不大
--select 列明 from 表名1  cross jion 表名2
--交叉示意圖

--學生與班級連接
select 學號,姓名,性別,學生.班級代碼,出生日期,班級.班級代碼,班級.班級名稱
    from 學生 cross join 班級

--內連接
--簡單連接,將兩個或多個表進行連接,只出現相匹配的記錄,不匹配的紀錄將無法查詢出來
--分類:等值連接(自然連接)、非等值連接、自連接
--等值連接
--連接條件是在where子句中給出的,只有滿足連接條件的性纔會出現在程序結果中
--select 列表列名 from 表名1 [inner] join 表名2 on 表名1.列名=表名2.列名
--或select 列表列名 from 表名1,表名2 where 表名1.列名=表名2.列名
--內連接示意圖

--查詢每個學生所在班級名稱
select 學號,姓名,性別,學生.班級代碼,班級.班級代碼,班級.班級名稱
    from 學生 inner join 班級 on 學生.班級代碼=班級.班級代碼

--自然連接
--在等值連接中,把目標列中重複的屬性去掉,成爲自然連接
select 學號,姓名,性別,學生.班級代碼,班級.班級名稱
    from 學生 inner join 班級 on 學生.班級代碼=班級.班級代碼

--非等值連接
--當連接條件中的關係運算符實用除‘=’以外的其他關係運算符時,這樣的內連接稱爲非等值連接(很少用到)

--自連接
--一個表與其自身進行連接稱爲表的自連接
--查詢與李鼕鼕同一個專業的教師信息
select Y.教師編號,Y.姓名,Y.專業
    from 教師 X,教師 Y
        where X.專業=Y.專業 and X.姓名='李鼕鼕' and Y.姓名!='李鼕鼕'

--Y X表的別名

--外連接
--指連接關鍵字join的後面表找那個指定列連接在前一個表中指定列的左邊或右邊,如果兩個表中的指定列都沒有匹配的行則返回空值
--左外連接 left outer join(左全部輸出)
--右外連接 right outer join(右全部輸出)
--全外連接 full outer join(左右全部輸出)
--outer可以省略不寫
--外連接示意圖

--左外連接實例
--查詢學生選課信息,包括沒有選課的學生信息
select 學生.學號,學生.姓名,選課.課程號
    from 學生 left join 選課
        on 學生.學號=選課.學號

--右外連接實例
--查詢被選修的課程信息,沒有被選的課程可也輸出
select 學號,選課.課程號,課程名,選課.成績 from 選課 right join 課程
    on 選課.課程號=課程.課程號

--全外連接
select 學號,選課.課程號,課程名,選課.成績 from 選課 full join 課程    
    on 選課.課程號=課程.課程號

--嵌套查詢
--將一個查詢語句嵌套在另一個查詢語句的where子句或having短語的條件中的查詢稱爲嵌套查詢
--在SELECT查詢語句中,子查詢也稱爲嵌套查詢,是一個嵌套在 SELECT中的查詢語句。處於內層的查詢稱爲子查詢,處於外層的查詢稱爲父查詢。
--任何允許使用表達式的地方都可以使用子查詢。T-SQL語句支持子查詢,正是SQL結構化的具體體現。
--子查詢SELECT語句必須放在括號中,子查詢叧返回一行數據,並且返回的數據常常也叧有一列
--可以用子查詢來檢查或者設置變量和列的值,或者用子查詢來測試數據行是否存在於WHERE子句中。
--注意: ORDER BY子句叧能對最終查詢結果排序,即在子查詢中的SELECT語句中不能使用ORDER BY子句。

--帶有IN謂詞的子查詢
--IN謂詞用於判斷一個給定值是否在子查詢結果集中。當父查詢表達式與子查詢的結果集中的某個值相等時,返回TURE,否
--則返回FALSE。同時,可以在IN關鍵字之前使用NOT,表示表達式的值不在查詢結果集中
--查詢至少有一門課程不及格的學生的信息
select 學生.姓名,姓名,班級代碼 from 學生 
    where 學號 in(select 學號 from 選課 where 成績<60)
--帶有比較運算符的子查詢
--查詢名叫‘王慶子’的學生的選課信息
select * from 選課 where 學號=(select 學號 from 學生 where 姓名='王慶子')
--查詢與李鼕鼕同一專業的教師信息,不包括李鼕鼕
select * from 教師 where 專業=(select 專業 from 教師 where 姓名='李鼕鼕') and 姓名!='李鼕鼕'
-- 帶有ANY、SOME或ALL關鍵字的子查詢
--ALL代表所有值,ALL指定的表達式要與子查詢結果集中的每個值都迚行比較,當表達式與每個值都滿足比較的關係時,才返回TRUE,否則返回FALSE。 
--SOME或ANY代表某些或者某個值,表達式叧要與子查詢結果集中的某個值滿足比較的關係時,就返回TRUE,否則返回FALSE
--查詢成績比王慶子同學高得學生選課信息
select * from 選課 where 成績>any(select  成績 from 選課  where 學號=(select 學號 from 學生 where 姓名='王慶子'))--any
select * from 選課
         where 成績>some(select  成績 from 選課  
                where 學號=(select 學號 from 學生 
                        where 姓名='王慶子'))

select * 
         from 選課
         where 成績>all(select  成績 
            from 選課  
                where 學號=(select 學號
                     from 學生 
                     where 姓名='王慶子'))

-- 帶有EXISTS謂詞的子查詢
--EXISTS稱爲存在量詞,WHERE子句中使用EXISTS表示當子查詢的結果非空時,條件爲TRUE,反之則爲FALSE。
--EXISTS前面也可以加NOT,表示檢測條件爲“不存在”,使用存在量詞NOT EXISTS後,若內層查詢結果爲空,則外層的WHERE子句返回真值,否則返回假值。
--EXISTS語句與IN非常類似,它們都根據來自子查詢的數據子集測試列的值。不同之處在於,EXISTS使用聯接將列的值與子查詢中的列聯接起來,而IN不需要聯接,它直接根據一組以逗號分隔的值迚行比較。
--查詢沒有選修課程號爲‘0001’
select * from 學生
where not exists (select * 
            from 選課
            where 學號=學生.學號 and 課程號='0001')

--查詢李鼕鼕同專業的教師,不含李鼕鼕
select * from 教師  x where exists (select * from 教師 y
where x.專業=y.專業 and y.姓名='李鼕鼕') and x.姓名!='李鼕鼕'

--查詢選修了全部課程的學生學號和姓名
--即不存在一門課程,所求學生沒有選擇它
select 學號 ,姓名 from 學生
where not exists (select * from 課程
where not exists(select * from 選課
where 學號=學生.學號 and 課程號=課程.課程號))

--聯合查詢
--把多個查詢的結果進行集合運算
--union 並
--union並,參與並運算操作的兩個查詢語句,其結果的列數必須相同,對於項的數據類型也必須相同
--查詢班級名稱爲'15級網絡技術301班'的女生和班級名爲'17級網絡技術301班'的男生信息
select * from 學生 where 性別='女' and 班級代碼=(select 班級代碼 from 班級 where 班級名稱='15級網絡技術301班')
union
select * from 學生 where 性別='男' and 班級代碼=(select 班級代碼 from 班級  where 班級名稱='17級網絡技術301班') 

--intersect 交操作符返回兩個查詢檢索出的共有行,即左右查詢中都出現的記錄
--查詢選修了分別含'政策'和'架構'兩個字的課程的學生名單
select 姓名
from 學生,選課,課程
where 學生.學號=選課.學號 and 選課.課程號=課程.課程號 and 課程名 like '%政策%'
intersect
select 姓名
from 學生,選課,課程
where 學生.學號=選課.學號 and 選課.課程號=課程.課程號 and 課程名 like '%架構%'

--except操作符返回將第二個查詢檢索出的行從第一個查詢檢索出的行中減去之後剩餘的行
--查詢選修了高等數學課,卻沒有選修'專業英語'的學生姓名
select distinct 姓名
from 學生,選課,課程
where 學生.學號=選課.學號 and 選課.課程號=課程.課程號 and 課程名='高等數學'
except
select 姓名
from 學生,選課,課程
where 學生.學號=選課.學號 and 選課.課程號=課程.課程號 and 課程名='專業英語'

--排序函數
--– ROW_NUMBER函數、 – RANK函數 – DENSE_RANK()函數 – NTILE()函數
--ROW_NUMBER()函數返回結果集分區內行的序列號,每個分區的第一行從1開始,返回類型爲bigint
--語法格式如下:• ROW_NUMBER() OVER([ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
select ROW_NUMBER() over (partition by 性別 order by 出生日期) as 年齡序號,姓名,性別,出生日期 from 學生
--BANK()函數返回結果集的分區內每行的排名。RANK()函數並不總返回連續整數。行的排名是相關行之前的排名數加一。 返回類型爲bigint
--語法格式如下:• RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )
--其中,partition_by_clause爲將FROM子句生成的結果集劃分爲要應用RANK()函數的分區;order_by_clause爲確定將RANK值應用於分區中的行時所基於的順序。
--安參加工作的時間對教師記錄進行排序
select RANK() OVER (ORDER BY 工作時間) AS 參建工作時間,姓名,工作時間 from 教師
--DENSE_RANK()函數返回結果集分區中行的排名,在排名中沒有任何間斷。行的排名等於所討論行之前的所有排名數加一。 返回類型爲bigint
--語法格式如下:
-- DENSE_RANK ( ) OVER ( [ <partition_by_clause> ] < order_by_clause > )
--• 其中,<partition_by_clause>將 FROM 子句生成的結果集劃分爲多個應用 DENSE_RANK函數的分區;<order_by_clause>確定將DENSE_RANK 函數應用於分區中各行的順序。
--安參加工作的時間對教師記錄進行排序,排序號連續
select DENSE_RANK() OVER (ORDER BY 工作時間) AS 參加工作先後 ,姓名,工作時間 from 教師
--NTILE()函數將有序(數據行)分區中的數據行分散到指定數目的組中。這些組有編號,編號從1開始。對於每一個數據行,NTILE將返回此數據行所屬的組的編號。返回類型爲bigint
--NTILE的Transact-SQL語法約定如下: NTILE (integer_expression) OVER ( [ <partition_by_clause> ] < order_by_clause > )
--參數的含義如下:
--(1)integer_expression:一個正整數常量表達式,用於指定每個分區必須被劃分成的組數。 integer_expression 的類型可以是int或bigint。 
--(2)<partition_by_clause>: 將FROM子句生成的結果集劃分成此函數適用的分區。 (3)<order_by_clause>:確定NTILE值分配到分區中各行的順序。當在排名函數中使用<order_by_clause> 時,不能用整數表示列
--把教師按照工作時間分爲四組
select NTILE(4) OVER (ORDER BY 工作時間) AS 參建工作先後組,姓名,工作時間 from 教師

--動態查詢
--動態查詢:根據實際需要臨時組裝成的SQL語句。 
--動態語句可以有完整的SQL語句組成,也可以根據操作分類,分別指定SELECT或INSERT等關鍵字,同時也可以指定查詢對象和查詢條件。
--動態SQL語句是在運行時有程序創建的字符串,他們必須是有效的SQL語句。
declare @cname char(20) 
set @cname='李鼕鼕'
select * from 教師 where 姓名=@cname

--exec 執行SQL
--普通SQL語句可以用Exec執行。例如下面的代碼:
--普通的SQL語句
 SELECT * FROM 課程
--利用EXEC執行SQL語句
 EXEC('SELECT * FROM 課程')  
 --使用擴展存儲過程執行SQL語句
 EXEC sp_executesql N'SELECT * FROM 課程'

 declare @cnam varchar(20) 
 set @cnam='課程名'
 --select @cname from 課程
 exec('select '+@cnam+' from 課程')

 

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