亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > SQL Server > 正文

SQL Server里ORDER BY的歧義性

2024-08-31 00:54:02
字體:
來源:轉載
供稿:網友
SQL Server里ORDER BY的歧義性

在今天的文章里,我想談下SQL Server里非常有爭議和復雜的話題:ORDER BY子句的歧義性。

視圖與ORDER BY

我們用一個非常簡單的SELECT語句開始。

1 -- A very simple SELECT statement2 SELECT * FROM Person.Person3 ORDER BY LastName4 GO

從剛才列出的代碼你可以看到,我們只想從Person.Person表以LastName列排序返回記錄。因為我們想能盡可能簡單的重用那個SQL語句,最后我們把它放到視圖里,如下:

1 -- This doesn't work2 CREATE VIEW v_Persons3 AS4     SELECT * FROM Person.Person5     ORDER BY LastName6 GO

但是你會看到,SQL Server不能創建那個視圖,只返回一個錯誤信息:

這個錯誤信息告訴你,的那個你不使用TOP,OFFSET或FOR xml表達式時,在視圖里你不允許使用ORDER BY子句。基于那個錯誤信息,我們可以通過增加TOP 100 PERCENT子句到視圖里在輕松修正問題。

1 -- Let's make it work!2 CREATE VIEW v_Persons3 AS4     SELECT TOP 100 PERCENT * FROM Person.Person5     ORDER BY LastName6 GO

現在視圖創建沒有任何問題!我們對視圖執行一個SELECT語句。

1 SELECT * FROM v_Persons2 GO

SELECT語句本身可以執行,但當你看返回的數據時,瘋狂的事情發生了:返回的數據沒有按LastName列排序——SQL Server按BusinessEntityID——表上的聚集鍵列排序!

這是SQL Server里的BUG么?不,并不是——它是“故意的”!我們來解釋下為什么。首先你要知道ORDER BY子句在SQL(編程語言本身)里用2個不同的上下文:

  1. 使用ORDER BY子句你可以定義返回給你客戶端程序的排序
  2. 另外ORDER BY子句用來定義從TOP表達式哪些行返回

你必須知道的最重要的事情是,你用視圖定義了所謂的集合(Set),行內函數,派生表,子查詢和通用表表達式(common table exPRessions(CTE))。集合是數學上的概念,關系數據庫(例如SQL Server)上集合論(Set Theory)的組成。集合本身是沒有排序的。因此用視圖定義與ORDER BY組合是不允許的——如你剛才所見。如果你嘗試這樣做,SQL Server不允許你這樣做并給你一個錯誤信息。

當然你可以在與TOP表達式里組合使用ORDER BY。但基本上你在愚弄SQL Server和你自己,因為ORDER BY沒有告訴SQL Server要以怎樣的排序返回數據給客戶端程序。假設你使用TOP 10 PERCENT。表的前10%是什么?你需要確定性的方式里定義排序。

而且因為我們必須使用TOP 100 PERCENT與ORDER BY組合,查詢優化器實際上在執行計劃里不會引入排序運算符。TOP 100 PERCENT意味著一切,因此如你在下圖所看到的,在執行計劃里TOP運算符不需要排序輸入。

在這個例子里,我們的返回行以從內在數據結構讀取的排序。這由SQL Server的存儲引擎來決定返回行的排序。這里我們從聚集索引里讀取行。因此我們拿到的數據按BusinessEntityID排序,這是索引列里聚集鍵值。

現在我們修改下視圖定義,從Person.Person表值返回10%的行。我們還是指定了ORDER BY子句。

1 -- Alter the view2 ALTER VIEW v_Persons3 AS4     SELECT TOP 10 PERCENT * FROM Person.Person5     ORDER BY LastName6 GO

當你現在看結果集時,你會看到返回的行按LastName列排序的?,F在才對了,因為你在執行計劃里看到了排序運算符(SQL Server 2014里沒有出現),因為TOP運算符最后能返回提供輸入行的前10%的數據。

當然你可以通過ORDER BY子句在你引用的視圖里按不同的排序返回10%的行給你的客戶端程序。

1 SELECT * FROM v_Persons2 ORDER BY FirstName3 GO

現在當你看執行計劃時,你會在計劃里看到2個(SQL Server 2014里只有1個)。

第1個(右邊)排序運算符為TOP運算符預排序(返回前10%)。第2個(左邊)排序運算符用來最后定義的排序,返回給客戶端程序。當你通過添加TOP 100 PERCENT來定義的視圖里強制ORDER BY——你基本上就在愚弄SQL Server……

沒有ORDER BY的TOP

另一個問題是沒有ORDER BY子句的TOP表達式不會提供你確定性的結果。我們可以用具體的例子演示下這個問題。假設有下列SELECT語句:

1 SELECT TOP 1 LastName FROM Person.Person2 GO

這個SQL語句用TOP 1表達式返回Person.Person表的第一行——沒有用ORDER BY子句定義排序。這個排序是基于執行計劃里選擇的索引。在這個例子里SQL Server返回你“Abbas”給你作為結果,因為這是執行計劃里查詢優化器選擇非聚集索引里第1條可用記錄。

因此從這個查詢返回的第1條記錄取決于執行計劃里選擇的索引。如果現在我們把非聚集索引停用呢。

1 -- Let's deactivate this index2 ALTER INDEX [IX_Person_LastName_FirstName_MiddleName] ON Person.Person3 DISABLE4 GO

然后當你再次執行剛才的SELECT語句,SQL Server返回你Sánchez值,意味只是在執行計劃里現在選擇的聚集索引的第1條記錄。SQL Server從聚集索引里返回了用BusinessEntityID值為1的第1行。

因此你與非確定性記錄打交道時:你的結果取決與執行計劃里選擇的索引!你可以通過增加ORDER BY子句來輕松實現查詢結果排序的明確性。在這個情況下ORDER BY子句為TOP表達式使記錄確定——這樣話在執行計劃里你會有Sort(Top N Sort)的運算符。

1 SELECT TOP 1 LastName FROM Person.Person2 ORDER BY LastName3 GO

在執行計劃里,SQL Server從哪個索引讀取行并不重要——Sort(Top N Sort)的運算符在執行計劃里會物理預排序行,并從它返回第N行——很簡單,是不是?

小結

在SQL(編程語言本身)里ORDER BY子句并不是一個最簡單的概念。如你在這篇文章里所學的,ORDER BY使用2個不同的上下文,因此你總要考慮下你要使用哪個上下文。永遠不要在視圖定義里增加TOP 100 PERCENT來愚弄SQL Server和你自己——它不會在最終的記錄集里體現排序。

感謝關注!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产在线高清精品| 欧美资源在线观看| 日韩精品中文字幕在线播放| 午夜精品久久久久久久白皮肤| 91亚洲va在线va天堂va国| 亚洲黄页视频免费观看| 欧美日韩午夜激情| 亚洲视频在线播放| 久久久精品国产网站| 91精品视频在线| 伦伦影院午夜日韩欧美限制| 日韩有码在线观看| 亚洲精品日韩丝袜精品| 日本不卡免费高清视频| 色综合色综合久久综合频道88| 国产精品aaaa| 欧美成人小视频| 91精品国产91久久久久| 中国日韩欧美久久久久久久久| 亚洲人成电影在线观看天堂色| 国产视频福利一区| 69视频在线免费观看| 日韩av一区在线观看| 亚洲天堂av高清| 91性高湖久久久久久久久_久久99| 欧美性极品xxxx做受| 国内精品模特av私拍在线观看| 国产欧美日韩精品在线观看| 91av视频在线观看| 国产精品jizz在线观看麻豆| 中文字幕亚洲精品| 久久久久久国产精品美女| 国产精品成人aaaaa网站| 成人国产精品色哟哟| 国产视频999| 国产亚洲欧洲在线| 韩国欧美亚洲国产| 国产精品视频白浆免费视频| 88国产精品欧美一区二区三区| 亚洲国产精品一区二区久| www欧美xxxx| 亚洲天堂精品在线| 亚洲第一天堂无码专区| 日韩欧美亚洲综合| 国产精品视频在线播放| 欧美日韩国产综合新一区| 国产精品私拍pans大尺度在线| 久久久久久高潮国产精品视| 亚洲一区二区自拍| 黑人巨大精品欧美一区二区免费| 国产视频丨精品|在线观看| 欧美色videos| 国产精品久久国产精品99gif| 欧美电影在线观看完整版| 亚洲韩国青草视频| 色777狠狠综合秋免鲁丝| 亚洲激情电影中文字幕| 97视频在线观看免费高清完整版在线观看| 色综合亚洲精品激情狠狠| 亚洲乱码一区av黑人高潮| 日韩av影视综合网| 中文字幕日韩av| 久久久精品一区二区三区| 日韩av在线免费观看一区| 亚洲三级av在线| www.日韩av.com| 综合136福利视频在线| 最近2019中文免费高清视频观看www99| 国产在线观看91精品一区| 日韩精品中文字| 国产精品丝袜久久久久久不卡| 色噜噜狠狠狠综合曰曰曰88av| 亚洲二区在线播放视频| 久久影院在线观看| 国产精品视频一区国模私拍| 九九热精品视频| 91视频国产精品| 91免费观看网站| 日韩av在线高清| 欧美日韩国产精品| 久久欧美在线电影| 欧美日韩亚洲成人| 久久久国产影院| 亚洲电影第1页| 国产精品成人av在线| 久久久免费av| 亚洲第五色综合网| 92裸体在线视频网站| 亚洲第一av在线| 久久视频在线直播| xxxx欧美18另类的高清| 亚洲电影免费观看高清完整版| 国产精品久久久久久久久久久新郎| 国产偷国产偷亚洲清高网站| 欧美日韩国产成人在线观看| 国产精品嫩草视频| 日韩av电影免费观看高清| 欧美视频在线观看免费网址| 国产日韩欧美电影在线观看| 亚洲男人的天堂在线| 国外成人在线播放| 欧美大尺度电影在线观看| 欧美情侣性视频| 国产美女久久久| 亚洲影视九九影院在线观看| 日韩三级成人av网| 欧美国产欧美亚洲国产日韩mv天天看完整| 欧美高清第一页| 7777kkkk成人观看| 国产日韩欧美视频在线| 国产精品吹潮在线观看| 欧美日韩在线一区| 不卡在线观看电视剧完整版| 欧美激情精品久久久久久变态| 久久精品国产96久久久香蕉| 日韩欧美亚洲范冰冰与中字| 91精品在线观看视频| 91免费在线视频网站| 日韩精品免费电影| 91av视频导航| 久久在精品线影院精品国产| 亚洲第一视频网| 奇门遁甲1982国语版免费观看高清| 日韩亚洲欧美中文高清在线| 国产精品va在线播放我和闺蜜| 性色av一区二区三区在线观看| 狠狠干狠狠久久| 91经典在线视频| 欧美精品午夜视频| 亚洲网站在线看| 亚洲国产欧美精品| 中文字幕亚洲激情| 亚洲男子天堂网| 18性欧美xxxⅹ性满足| 国产精品777| 精品久久久久久久久久国产| 成人春色激情网| 国产不卡精品视男人的天堂| 国产综合视频在线观看| 国产精品91视频| 久久人人爽人人爽人人片亚洲| 伊人伊成久久人综合网站| 国内精品久久久久久影视8| 深夜福利国产精品| 亚洲国产欧美一区二区丝袜黑人| 亚洲va码欧洲m码| 亚洲aaaaaa| 欧美性猛交xxxxx水多| 美女视频久久黄| 国产这里只有精品| 久久久av亚洲男天堂| 久久久久久久久久久久久久久久久久av| 欧美日韩性视频在线| 8090成年在线看片午夜| 久久精品中文字幕| 久久精品国产欧美亚洲人人爽| 亚洲直播在线一区| 亚洲一区二区三区成人在线视频精品| 精品国产乱码久久久久久虫虫漫画| 亚洲天堂精品在线| 欧美成人中文字幕| 亚洲欧美在线播放| 国产+人+亚洲| 97在线视频国产|