翻譯|使用教程|編輯:莫成敏|2020-03-18 14:14:01.750|閱讀 374 次
概述:本文解釋了為什么ORDER BY子句應(yīng)始終使用其名稱或別名來(lái)指定排序列,而不是使用整數(shù)來(lái)指定列在SELECT列表中的位置。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
SQL Prompt是一款實(shí)用的SQL語(yǔ)法提示工具。它根據(jù)數(shù)據(jù)庫(kù)的對(duì)象名稱、語(yǔ)法和代碼片段自動(dòng)進(jìn)行檢索,為用戶提供合適的代碼選擇。自動(dòng)腳本設(shè)置使代碼簡(jiǎn)單易讀--當(dāng)開(kāi)發(fā)者不大熟悉腳本時(shí)尤其有用。SQL Prompt安裝即可使用,能大幅提高編碼效率。此外,用戶還可根據(jù)需要進(jìn)行自定義,使之以預(yù)想的方式工作。
本文解釋了為什么ORDER BY子句應(yīng)始終使用其名稱或別名來(lái)指定排序列,而不是使用整數(shù)來(lái)指定列在SELECT列表中的位置。
盡管有可能做到這一點(diǎn),但ANSI SQL-92是最后一個(gè)仍支持在ORDER BY子句中使用整數(shù)(select_list_number)的標(biāo)準(zhǔn),隨后又從ANSI SQL-99標(biāo)準(zhǔn)中刪除了該標(biāo)準(zhǔn)。包括SQL Server在內(nèi)的主要SQL RDBMS仍然支持它,并且沒(méi)有棄用通知,但是它在Microsoft即將淘汰的SQL Server功能列表中。
如果您不指定實(shí)際的列名,不僅使語(yǔ)句更難以理解,而且對(duì)SELECT列表的任何后續(xù)更改(例如更改列順序或添加新列)都需要檢查ORDER BY子句,并且很可能對(duì)其進(jìn)行了修改,以避免產(chǎn)生意外結(jié)果。另外,使用常量并不總是有效的,例如使用常量來(lái)指定出現(xiàn)在排名函數(shù)中的表達(dá)式時(shí)。
SQL Prompt的最佳實(shí)踐代碼分析規(guī)則BP002 –ORDER BY子句中包含常量,這意味著在ORDER BY子句中對(duì)常量的任何使用都要加上綠色的下劃線。
為什么在ORDER BY子句中允許使用常量?
想象一下,你需要為AdventureWorks的人力資源經(jīng)理準(zhǔn)備一份員工詳細(xì)信息列表:
SELECT Person.FirstName + ' ' + Coalesce(Person.MiddleName + ' ', '') + Person.LastName + ': ' + Coalesce(Person.Suffix + ' ', '') + Coalesce('(' + Person.Title + ') ', '') + Employee.JobTitle AS employee, Employee.NationalIDNumber, Employee.BirthDate, Employee.MaritalStatus, Employee.Gender, Employee.HireDate, Employee.SalariedFlag, Employee.VacationHours, Employee.SickLeaveHours FROM HumanResources.Employee INNER JOIN Person.Person ON Person.BusinessEntityID = Employee.BusinessEntityID;
沒(méi)有指定排序,因此當(dāng)前排序是隨機(jī)的。您現(xiàn)在意識(shí)到需要按員工姓名訂購(gòu):
SELECT Person.FirstName + ' ' + Coalesce(Person.MiddleName + ' ', '') + Person.LastName + ': ' + Coalesce(Person.Suffix + ' ', '') + Coalesce('(' + Person.Title + ') ', '') + Employee.JobTitle AS employee, Employee.NationalIDNumber, Employee.BirthDate, Employee.MaritalStatus, Employee.Gender, Employee.HireDate, Employee.SalariedFlag, Employee.VacationHours, Employee.SickLeaveHours FROM HumanResources.Employee INNER JOIN Person.Person ON Person.BusinessEntityID = Employee.BusinessEntityID ORDER BY employee;
到處都是微笑。這是有效的。很久以前,有一段時(shí)間它不起作用。當(dāng)時(shí),使用SQL,如果您希望按涉及一列或多列的表達(dá)式進(jìn)行排序,則SQL無(wú)法做到這一點(diǎn)。這是因?yàn)樵趫?zhí)行排序時(shí),沒(méi)有明顯的方法知道結(jié)果中表達(dá)式的值。而且,奇怪的是,當(dāng)時(shí)的SQL標(biāo)準(zhǔn)要求您只能在SELECT語(yǔ)句中指定一列作為ORDER BY子句中的參數(shù)。
在ORDER BY子句中使用表達(dá)式
然后,SQL允許在ORDER BY子句中使用表達(dá)式。如果其中一列是表達(dá)式,并且您想按其排序,則ORDER BY子句中的表達(dá)式必須與SELECT表源語(yǔ)句中使用的表達(dá)式完全匹配:
SELECT Person.FirstName + ' ' + Coalesce(Person.MiddleName + ' ', '') + Person.LastName + ': ' + Coalesce(Person.Suffix + ' ', '') + Coalesce('(' + Person.Title + ') ', '') + Employee.JobTitle AS employee, Employee.NationalIDNumber, Employee.BirthDate, Employee.MaritalStatus, Employee.Gender, Employee.HireDate, Employee.SalariedFlag, Employee.VacationHours, Employee.SickLeaveHours FROM HumanResources.Employee INNER JOIN Person.Person ON Person.BusinessEntityID = Employee.BusinessEntityID ORDER BY Person.FirstName + ' ' + Coalesce(Person.MiddleName + ' ', '') + Person.LastName + ': ' + Coalesce(Person.Suffix + ' ', '') + Coalesce('(' + Person.Title + ') ', '') + Employee.JobTitle;
這不僅繁瑣,而且如果您開(kāi)始擺弄列表達(dá)式并忘記更改ORDER BY以匹配它,則可能突然導(dǎo)致查詢運(yùn)行緩慢,如果不一致的話:
SELECT Person.FirstName + ' ' + Coalesce(Person.MiddleName + ' ', '') + Person.LastName + ': ' + Coalesce(Person.Suffix + ' ', '') + Coalesce('[' + Person.Title + '] ', '') + Employee.JobTitle AS employee, Employee.NationalIDNumber, Employee.BirthDate, Employee.MaritalStatus, Employee.Gender, Employee.HireDate, Employee.SalariedFlag, Employee.VacationHours, Employee.SickLeaveHours FROM HumanResources.Employee INNER JOIN Person.Person ON Person.BusinessEntityID = Employee.BusinessEntityID ORDER BY Person.FirstName + ' ' + Coalesce(Person.MiddleName + ' ', '') + Person.LastName + ': ' + Coalesce(Person.Suffix + ' ', '') + Coalesce('(' + Person.Title + ') ', '') + Employee.JobTitle;
由于表達(dá)式不匹配,此版本的查詢運(yùn)行速度降低了25%。沒(méi)什么大不了的,卻讓人生氣,看上去很笨拙。
在ORDER BY子句中使用常量
SQL最初通過(guò)允許您在ORDER BY表達(dá)式中指定一個(gè)與要排序的表表達(dá)式中的列號(hào)相對(duì)應(yīng)的整數(shù)常量來(lái)解決該問(wèn)題,而沒(méi)有解決潛在的缺陷。現(xiàn)在可以將SQL Server中的排序列指定為名稱或列別名,或表示該列在選擇列表中位置的正整數(shù)。這是不明智的,因?yàn)檫@意味著如果您更改SELECT語(yǔ)句中的列順序,那么事情就會(huì)出錯(cuò)。當(dāng)ORDER BY表達(dá)式出現(xiàn)在排名函數(shù)中時(shí),它也不起作用。
SELECT Person.FirstName + ' ' + Coalesce(Person.MiddleName + ' ', '') + Person.LastName + ': ' + Coalesce(Person.Suffix + ' ', '') + Coalesce('(' + Person.Title + ') ', '') + Employee.JobTitle, Employee.NationalIDNumber, Employee.BirthDate, Employee.MaritalStatus, Employee.Gender, Employee.HireDate, Employee.SalariedFlag, Employee.VacationHours, Employee.SickLeaveHours FROM HumanResources.Employee INNER JOIN Person.Person ON Person.BusinessEntityID = Employee.BusinessEntityID ORDER BY 1;
結(jié)論
微軟很久以前修復(fù)了SQL Server查詢優(yōu)化器中的原始潛在缺陷,即您無(wú)法通過(guò)其別名引用多列表達(dá)式,因?yàn)樵趦?yōu)化過(guò)程中此時(shí)別名的值未知。現(xiàn)在這很簡(jiǎn)單,但是在此期間,編寫了許多代碼來(lái)指定ORDER BY子句中的列號(hào)。它使表達(dá)式看起來(lái)更整潔并節(jié)省了一些擊鍵。他們看起來(lái)好像運(yùn)行得更快,但是共享與完整表達(dá)式排序相同的執(zhí)行計(jì)劃。在2000年前,從SQL標(biāo)準(zhǔn)中刪除了使用整數(shù)常量的快速解決方案,但是其使用壽命很奇怪。建立功能后,很難刪除它。
本文內(nèi)容到這里就結(jié)束了,希望對(duì)您有所幫助~您可以繼續(xù)關(guān)注我們慧都網(wǎng),了解更多產(chǎn)品資訊,或者下載SQL Prompt試用版免費(fèi)體驗(yàn)~
相關(guān)內(nèi)容推薦:
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: