SQL語句的各個症結字的解析進程具體總結。本站提示廣大學習愛好者:(SQL語句的各個症結字的解析進程具體總結)文章只能為提供參考,不一定能成為您想要的結果。以下是SQL語句的各個症結字的解析進程具體總結正文
因為比來須要做一些sql query機能晉升的研討,是以研討了一下sql語句的處理進程。在園子裡看了下,年夜家寫了許多相干的文章,年夜家的著重點各有分歧。本文是我在看了各類材料背工機總結的,會具體的,一步一步的講述一個sql語句的各個症結字的解析進程,迎接年夜家相互進修。
SQL語句的解析次序簡略的說一個sql語句是依照以下的次序解析的:
1. FROM FROM前面的表標識了這條語句要查詢的數據源。和一些子句如,(1-J1)笛卡爾積,(1-J2)ON過濾,(1-J3)添加內部列,所要運用的對象。FROM進程以後會生成一個虛擬表VT1。起首創立一個Customers表,拔出以下數據:
創立一個Orders表,拔出以下數據:
假設我們想要查詢來自Madrid的,定單數小於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
查詢成果為:
上面我們會具體的講述sql是如何盤算出這個成果的:
FROM子句FROM子句標識了須要查詢的表,假如指定了表操作,會從左到右的處置,每個基於一個或許兩個表的表操作都邑前往一個輸入表。右邊表的輸入成果會作為下一個表操作的輸出成果。例如,交表相干的操作有 (1-J1)笛卡爾積,(1-J2)ON過濾器,(1-J3)添加內部列。FROM句子生成虛擬表VT1。
Step 1-J1:履行笛卡爾積(CROSS JOIN)笛卡爾積會把閣下兩個表每行一切能夠的組合都列出來生成表VT1-J1,假如左表有m列,右表有n列,那末笛卡爾積以後生成的VT1-J1表將會有m×n列。
Step 1-J1這個步調等價於履行:
SELECT * from Customers C CROSS JOIN Orders O
履行成果為:(共有4×7列)
ON過濾前提是sql的三個過濾前提(ON,WHERE,HAVING)中最早履行的,ON過濾前提運用於前一步生成的虛擬表(VT1-J1),知足ON過濾前提的行會被參加到虛擬表VT1-J2中。在運用了ON 過濾以後,生成的VT1-J2表以下所示:
這個步調只會湧現在應用了外銜接的情形。關於外銜接(LEFT,RIGHT, or FULL),你可以標志一個或許兩個表作為保存表。作為保存表意味著你願望這個內外面的一切列都被前往,即便它外面的數據不知足ON子句的過濾前提。LEFT OUTER JOIN 把右邊的表標志為保存表,RIGHTOUTER JOIN把左邊的表作為保存表,FULL OUTER JOIN把兩個表都標志為保存表.Step 1-J3為依據VT1-J2中的虛擬表,添加了保存表中不知足ON 前提的列,在未保存表中沒有對應的列,是以標志為NULL。這個進程生成了虛擬表VT1-J3。
假如FROM子句中有多個表操作運算,sql會依照從左到右的次序處置,右邊生成的暫時表成果作為左邊表的輸出表。
Step 2 WHERE 子句WHERE過濾被運用到前一步生成的暫時表中,依據WHERE過濾前提生成暫時表VT2。
留意:因為數據如今還沒有被分組,是以如今你不克不及應用聚合運算-例如:你不克不及應用如許的句子 WHERE orderdate = MAX(orderdate)。別的你也不克不及應用SELECT子句中創立的變量別號,由於如今還沒有處置SELECT子句-例如你不克不及寫如許的句子:SELECT YEAR(orderdate) AS orderyear . . . WHERE orderyear > 2008.
運用這個過濾
WHERE C.city = 'Madrid'
這時候生成的暫時表VT2的內容以下:
在這個例子中,你須要在ON子句中應用ON C.customerid = O.customerid過濾,沒有定單的客戶在1-J2這一步中被過濾失落,然則在1-J3這一步中作為內部列又被加回來。然則,因為你只想前往來自Madrid的客戶,是以你須要在WHERE子句中過濾城市(WHERE C.city = ‘Madrid'),假如你放在ON過濾中,不屬於Madrid的客戶在添加內部列中會被添加回來。
關於ON 和 WHERE 的差別須要在這裡解釋一下,ON 和WHERE 的重要差別在於 ON 其實添加內部列之進步行過濾,WHERE 是在以後。ON過濾失落的列會在1-J3中添加回來。假如你不須要添加內部列,那末這兩個過濾是雷同的。
Step 3 GROUP BY子句這個子句會把前一步中生成的暫時表中的數據停止分組,每行都邑分到而且只分到一個組裡,生成虛擬表VT3。VT3表中包括了VT2表中一切的數據,和分組標識符。
這是生成的暫時表VT3的內容以下:
sql終究前往的成果中,每個分組必需只能前往一行(除非被過濾失落),是以當一個sql語句中應用了GROUP BY時,在GROUP BY前面處置的子句,如SELECT,HAVING子句等,只能應用湧現在GROUP BY前面的列,關於沒有湧現GROUP BY前面的列必需應用聚合函數(如 MAX ,MIN,COUNT,AVG等),包管每個GROUP只前往一行。
Step 4 HAVING子句HAVING子句用來過濾前一步生成的暫時表,而且只感化於分組後的數據,知足HAVING前提的GROUP被添加到虛擬表VT4中。
當運用了這個過濾:
HAVING COUNT(O.orderid) < 3
以後,生成的VT4表內容以下:
須要留意的一點是,這外面應用的是COUNT(O.orderid),而不是COUNT(*),因為這個查詢中添加了內部列,COUNT辦法會疏忽NULL的列,招致湧現了你不想要的成果。
Step 5 SELECT 子句雖然湧現在sql語句的最後面,SELECT在第五步的時刻才被處置,SELECT子句前往的表會終究前往給挪用者。這個子句包括三個子階段:(5-1)盤算表達式,(5-2) 處置DISTINCT,(5-3)運用TOP過濾。
Step 5-1 盤算表達式
SELECT子句中的表達式可以前往或許操作前一步表中前往的根本列。假如這個sql語句是一個聚合查詢,在Step 3以後,你只能應用GROUP BY中的列,對不屬於GROUP聚集中的列必需應用聚合運算。不屬於FROM表中根本列的必需為其起一個體名,如YEAR(orderdate) AS orderyear。
留意:在SELECT子句中創立的別號,不克不及在之前的Step中應用,即便在SELECT子句中也不克不及。緣由是sql的許多操作是同時操作(all at once operation),至於甚麼是all-at-once operation這裡就不再引見了。是以,SELECT子句中創立的別號只能在前面的子句中應用,如ORDER BY。例如:SELECT YEAR(orderdate) AS orderyear . . . ORDER BY orderyear。
在這個例子中:
SELECT C.customerid, COUNT(O.orderid) AS numorders
成果會獲得一個虛擬表VT5-1:
Step 5-2:運用DISTINCT子句
假如sql語句中應用了DISTINCT,sql會把反復列去失落,生成虛擬表VT5-2。
Step 5-3:運用TOP選項
TOP選項是T-SQL供給的一個功效,用來表現顯示若干行。基於ORDER BY子句界說的次序,指定個數的列會被查詢出來。這個進程生成虛擬表VT5-3。
正如上文提到的,這一步依附於ORDER BY界說的次序來決議哪些列應當顯示在後面。假如你沒有指定成果的ORDER BY次序,也沒有應用WITH TIES子句 ,每次的前往成果能夠會紛歧致。
在我們的例子中,Step 5-3被省略了,由於我們沒有應用TOP症結字。
Step 6:ORDER BY子句前一步前往的虛擬表在這一步被排序,依據ORDER BY子句指定的次序,前往游標VC6。ORDER BY子句也是獨一一個可使用SELECT子句創立的別號的處所。
留意:這一步和之前分歧的處所在於,這一步前往的成果是一個游標,而不是表。sql是基於聚集實際的,一個聚集沒有對他的行界說次序,它只是一個成員的邏輯聚集,是以成員的次序其實不主要。帶有ORDER BY子句的sql前往一個依照特定序列組織每行的對象。ANSI 把如許的一個對象叫游標。懂得這一點對你懂得sql很主要。
下面的步調如圖所示:本書中重要內容是參照 Inside Microsoft SQL Server 2008:T-SQL Query,中的內容,年夜家假如想深刻懂得sql查詢相干的常識,可以找這本書看看,我這有英文原版的pdf,須要的可以找我要。