Advanced Transact-SQL for SQL Server 2000 学习译文
? 在這章中,你將寫代碼,許多的將運行在一個人力資源數據庫這是一個假想的膠乳橡膠制造公司其他的代碼在本章中將運行在Northwind 首先創建數據庫表
CREATE TABLE Departments
(
?Deptno int NOT NULL
?CONSTRAINT PK_dept_deptno PRIMARY KEY,
?deptname varchar(15) NOT NULL
)
CREATE TABLE Jobs
(
?jobid int NOT NULL
?CONSTRAINT PK_jobs_jobid PRIMARY KEY,
?jobdesc varchar(15) NOT NULL
)
CREATE TABLE Employees
(
?empid int NOT NULL
?CONSTRAINT PK_emps_empid PRIMARY KEY,
?empname varchar(10) NOT NULL,
?deptno int NULL
?CONSTRAINT FK_emps_depts
?REFERENCES Departments(deptno),
?jobid int NOT NULL
?CONSTRAINT FK_emps_jobs REFERENCES Jobs(jobid),
?salary decimal(7,2) NOT NULL
)
INSERT INTO Departments VALUES(100, 'Engineering')
INSERT INTO Departments VALUES(200, 'Production')
INSERT INTO Departments VALUES(300, 'Sanitation')
INSERT INTO Departments VALUES(400, 'Management')
INSERT INTO Jobs VALUES(10, 'Engineer')
INSERT INTO Jobs VALUES(20, 'Worker')
INSERT INTO Jobs VALUES(30, 'Manager')
INSERT INTO Jobs VALUES(40, 'Cleaner')
INSERT INTO Employees VALUES(1, 'Leo', 400, 30, 10000.00)
INSERT INTO Employees VALUES(2, 'George', 200, 20, 1000.00)
INSERT INTO Employees VALUES(3, 'Chris', 100, 10, 2000.00)
INSERT INTO Employees VALUES(4, 'Rob', 400, 30, 3000.00)
INSERT INTO Employees VALUES(5, 'Laura', 400, 30, 3000.00)
INSERT INTO Employees VALUES(6, 'Jeffrey', NULL, 30, 5000.00)
看人力資源數據庫的架構
由于這里上傳圖片比較麻煩我就不把結構圖放上來啦 內部連接 縮寫形式的select語句 select <select_list> FROM <table_source> [where <search_condition>] 在OLD-STYLE語法中,內部連接的情況下,是sql-89兼容,<table-source>包含列表以逗號分隔的表和<search_condition>包含連接條件見下sql SELECT <select_list> from T1,T2 WHERE <join_condition> [AND <filter>] 如果你想獲得員工和部門信息,你寫查詢語句如下 SELECTempid,
empname,
salary,
E.deptno,
deptname
FROM
Employees AS E,
Departments AS D
WHERE
E.deptno = D.deptno SQL?92 連接語法 SELECT
<select_list>
FROM
T1
<join_type> JOIN
T2 [ON <join_condition>]
[<join_type> JOIN
T3 [ON <join_condition>]
[WHERE
<filter>] SQL?92 Two?Way 內連接 下面是92語法縮寫形式 SELECT
<select_list>
FROM
T1
[INNER] JOIN
T2 ON <join_condition>
[WHERE
<filter>] INNER 可以寫也可以不寫 因為他是默認的連接類型,你可以寫如下的查詢語句 92語法 select empid,empname,salary,E.deptno,deptname from Employees as E join Departments as d on E.deptno = D.deptno 如果你想添加工作簡要信息你也可以添加查詢 SELECT
empid,
empname,
salary,
E.deptno,
deptname,
E.jobid,
jobdesc
FROM
Employees AS E,
Departments AS D,
Jobs AS J
WHERE
E.deptno = D.deptno
AND
E.jobid = J.jobid SQL?92 Three?Way Inner Joins SELECT
empid,
empname,
salary,
E.deptno,
deptname,
E.jobid,
jobdesc
FROM
Employees AS E
JOIN
Departments AS D ON E.deptno = D.deptno
JOIN
23 Jobs AS J ON E.jobid = J.jobid 一個常見的問題,程序員詢問的關于加入多于兩個表的順序是否影響查詢的性能 在內部連接中不會有影響, 查詢處理器會意識到這一點,會決定內部順序訪問根據表成本估計的 交叉查詢? Cross Joins 交叉連接產生的笛卡爾乘積表進行 SELECT
deptname,
jobdesc
FROM
Departments,
Jobs 92語法 SELECT
deptname,
jobdesc
FROM
Departments
CROSS JOIN
Jobs Outer Joins? 外部連接查詢 外部連接使你能夠定義任意一個或兩個參與連接的表,這意味著重這兩個表中返回匹配的行,同時也會返回表中沒有匹配的行返回的行用null來代替,sql-89不支持該語法 Listing 1?13: Old?Style Outer Join Syntax SELECT
<select_list>
FROM
T1,
T2
WHERE
T1.key_col {*= | =*} T2.key_col [AND <filter>] 如果星號是等號左邊,表的聯接條件的左側是保留表。這被稱為左外部聯接。 讓我們在生產員工和部門信息,保留所有的 old?style 語法編寫一個查詢從雇員表中,行即使有沒有匹配的部門,如清單 1?14 顯示。 SELECT
*
FROM
Employees AS E,
Departments AS D
WHERE
E.deptno *= D.deptno SQL?92 Two?Way Outer Joins SELECT
<select_list>
FROM
T1
{LEFT | RIGHT | FULL} [OUTER] JOIN
T2 ON <join_condition>
[WHERE
<filter> SQL?92 Two?Way Left Outer Joins SELECT
*
FROM
Employees AS E
LEFT OUTER JOIN
Departments AS D ON E.deptno = D.deptno 此時員工會全部查詢出來當遇到員工沒有對應的部門的時候將用null替換 如果你想保留表Departments所有行,則你可以寫一個簡單的右查詢 SELECT
*
FROM
Employees AS E,
Departments AS D
WHERE
E.deptno =* D.deptno SQL?92 Two?Way Right Outer Joins SELECT
* FROM
Employees AS E
RIGHT OUTER JOIN
Departments AS D ON E.deptno = D.deptno 如果你想保留所有的人員和所有的部門你可以寫一個查詢語句 Listing 1?19: SQL?92 Two?Way Full Outer Join SELECT
*
FROM
Employees AS E
FULL OUTER JOIN
Departments AS D ON E.deptno = D.deptno 你想查詢出所有員工工作和和員工信息,同時查看部門信息則可以寫如下sql SELECT
*
FROM
Employees AS E
LEFT OUTER JOIN
Departments AS D ON E.deptno = D.deptno
RIGHT OUTER JOIN
Jobs AS J ON E.jobid = J.jobid 左和右外部聯接,與表在查詢中的顯示的順序確定的順序及其處理 它們的順序會影響輸出順序,但是并不影響整個輸出,所以不能確定他們的處理順序 --------考慮到比較亂所以重新整理----------- 知識點描述? 一下全部是個人看本書的一些理解如果有不全的地方請各位大牛指出謝謝 1? sql 每個步驟都會產生一個虛擬表,作為下一個步驟的數據源,同時這些虛擬表對擁有者是沒有權限操作的。只有最后返回表才屬于擁有者 Customers/Orders場景下的查詢 分析如下sql(該查詢返回Maidrid且訂單數少于3的消費者,并包含他們的訂單數。查詢結果排序,重小到大。 SELECT C.customerid,count(O.orderid) as numorders FROM dbo.Customers as c left outer join dbo.Orders as O ON C.customerid = O.customerid where c.city = 'Madrid' GROUP BY C.customerid HAVING COUNT(O.orderid) < 3 ORDER BY NUMORDERS; 邏輯查詢步驟詳解釋 1 執行笛卡爾 對from子句的前兩個表執行笛卡爾生成虛擬表VT1 VT1表結構 VT1行 VT1 左邊表的行和右邊表的行的每個可能的組合都包含一行。如果左表包含m行 右表包含n行則總共VT1表可以產生m*n行 VT1的列結構 VT1的列由該列的原表名限定。 步驟 2 應用ON帥選器 查詢帥選器有三個ON、WHERE、HAVING ON帥選器中的邏輯表達式被應用到上一步返回的虛擬表中的所有行。 只有連接條件為true的那些行才會包含在步驟2返回的虛擬表VT2中 三值邏輯 sql中的邏輯表達式的可能值包括TRUE? FALSE? UNKNOWN. 他們被稱為三值邏輯。 sql中的UNKNOWN邏輯值通常出現在包含null值的邏輯表達式中如 下面表達式的邏輯值都是unknown null > 42??? null = null; 2 not unknown 還是等于 unknown UNKNOWN邏輯結果和null在不同的語言元素中被區別對待。 查詢帥選器都把unknown當作false處理。 check約束中的unknown值被當做true對待 如果表中有一列定義了unique約束,將無法向表中插入該列值為null的兩行 group by 子句把所有的null值分到一組 order by 子句把所有的null值排列在一起 步驟3 添加外部行 通過添加一個外部關聯標識可以把其中一個或者兩個表作為保留表。保留表則返回所有行。 這一步會生成虛擬表VT3 步驟4 應用where帥選器 對上一步虛擬表中的所有行進行where帥選只有符合條件的才會返回生產虛擬表VT4 注意因為數據還沒有分組,現在還不能使用聚合帥選器。 ON 在添加外部行(步驟三 外部連接)之前應用,而where是在步驟三之后才應用。ON 帥選器對保留表中的部分行的移除并不是最終的。因為步驟三會把這些行添加回來。而where帥選器對行的移除是最終的。 5 分組 group by 子句中列表的每個唯一值組合為一組,上一步返回的每個基行被分配到一個組,且僅僅分配到一個組。得到虛擬表VT5 VT5由兩部分組成實際組構成組部分和上一步返回的基行構成一部分。 如果在查詢中指定啦group by 子句 則后面的所有步驟只能指定可以為成組得到標量值的表達式。 這一階段認為兩個null是相等的也就是說所有的null會被分配到一起 group by 子句的輸入是上一步返回的虛擬表。 如果你指定group by all 在第四部被移除的組將被添加到這一步的結果虛擬表其中的原始部分包含空集合。 步驟6 步驟7 只有符合having 條件的才會成為這一步返回的虛擬表VT6的一部分,HAVING 是第一個也是唯一一個應用到已分組數據的帥選器 步驟8 處理select列表 select列表中的表達式可以是由上一步返回的虛擬表的基列,也可以說對這些列的操作。 前面曾經提到過,如果查詢是一個聚合查詢,在第五步以后你只能引用上一步所返回的虛擬表中那些組成部分指定的基列(group by 列表)如果你引用啦原始部分中的列必須進行聚合運算。
轉載于:https://www.cnblogs.com/yuanxiang/archive/2012/05/20/2510575.html
總結
以上是生活随笔為你收集整理的Advanced Transact-SQL for SQL Server 2000 学习译文的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP中的参数提示
- 下一篇: 网页标准HTML5标准较量正酣