国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > SQL Server > 正文

針對distinct疑問引發(fā)的一系列思考

2024-08-31 01:03:31
字體:
供稿:網(wǎng)友

有人提出了這樣一個問題,整理出來給大家也參考一下

假設(shè)有如下這樣一張表格:

針對distinct疑問引發(fā)的一系列思考

這里的數(shù)據(jù),具有如下的特征:在一個DepartmentId中,可能會有多個Name,反之也是一樣。就是說Name和DepartmentId是多對多的關(guān)系。

現(xiàn)在想實現(xiàn)這樣一個查詢:按照DepartmentID排完序之后(第一步),再獲取Name列的不重復(fù)值(第二步),而且要保留在第一步后的相對順序。以本例而言,應(yīng)該返回三個值依次是:ACB

我們首先會想到下面這樣一個寫法

select distinct name from Sample order by DepartmentId

從語義上說,這是很自然的。但是很可惜,這個語句根本無法執(zhí)行,錯誤消息是:

針對distinct疑問引發(fā)的一系列思考

這個錯誤的意思是,如果使用了DISTINCT(去重復(fù)值),則出現(xiàn)在OrderBy后面的字段,必須也出現(xiàn)在SELECT后面,但如果DepartmentID如果也真的出現(xiàn)在SELECT后面,顯然是不會有重復(fù)值的,所以結(jié)果肯定也是不對的。

select distinct name,DepartmentId from Sample order by DepartmentId

 

針對distinct疑問引發(fā)的一系列思考

那么,既然DISINCT 與OrderBy結(jié)合起來用會有這個的一個問題,我們是否有可能變通一下,例如下面這樣:

SELECT distinct a.NameFROM (select top 100 percent name from Sample order by DepartmentId) a

想比較之前的寫法,我們用到了子查詢技術(shù)。同樣從語義上看,仍熱是很直觀明了的。我想先按照DepartmentId進(jìn)行排序, 然后再去重復(fù)值。但是返回到結(jié)果是下面這樣的:

針對distinct疑問引發(fā)的一系列思考

雖然確實去除了重復(fù)值,但返回的順序卻是不對的。我們希望是先按照DepartmentId排序之后,然后去除重復(fù)值,并且保留排序后的相對順序。

為什么會出現(xiàn)上面這個結(jié)果呢?其實是因為DISTINCT本身是會做排序的,而且這個行為是無法更改的(下圖的執(zhí)行計劃中可以看到這一點)。所以其實我們之前做的Order by在這里會失去意義。【實際上,如果觀察ADO.NET Entity Framework等ORM工具中生成的類似的一個查詢,它會自動丟棄Order by的設(shè)置】

針對distinct疑問引發(fā)的一系列思考

那么,這樣的情況下,是不是就不可能實現(xiàn)需求了呢?雖然說,這個需求并不多見,絕大部分時候,DISTINCT作為最后一個操作,做一次排序是合乎情理的。

我是這樣考慮到,既然DISTINCT的這個行為是內(nèi)置的,那么是否可以繞過這個操作呢?最終我用的一個解決方案是:我能不能把每個Name都編上一個編號,例如有兩個A的話,第一個A我為它編號為1,第二個編號為2,以此類推。然后,查詢的時候,我先排序,然后篩選那些編號為1的Name,這樣其實也就實現(xiàn)了去重復(fù)值了。

針對distinct疑問引發(fā)的一系列思考

SQL Server 2005開始提供了一個ROW_NUMBER的功能,結(jié)合這個功能,我實現(xiàn)了下面這樣的查詢:

select a.Name from (select top 100 percentName,DepartmentId,ROW_NUMBER() over(partition by name order by departmentid) rowfrom Sample order by DepartmentId) awhere a.row=1order by a.DepartmentId

然后,我得到了下面這樣的結(jié)果,我推敲下來,這應(yīng)該是符合了之前提到的這個需求的

針對distinct疑問引發(fā)的一系列思考

相比較而言,這個查詢的效率會低一些,這個是可以預(yù)見的(可以通過下圖看出一點端倪)。但如果需求是硬性的,那么犧牲一些性能也是不奇怪的。當(dāng)然,我們可以再研究看看是否有更優(yōu)的一些寫法。無論如何,使用內(nèi)置標(biāo)準(zhǔn)的實現(xiàn),通常都是相對較快的。

以上就是關(guān)于distinct疑問引發(fā)的一系列思考,希望對大家的學(xué)習(xí)有所幫助。


注:相關(guān)教程知識閱讀請移步到MSSQL教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 丹棱县| 射阳县| 铜山县| 八宿县| 旌德县| 那坡县| 金川县| 休宁县| 通化县| 大足县| 宁波市| 高要市| 东安县| 乐清市| 三都| 伊宁市| 五寨县| 马公市| 巴南区| 外汇| 宁津县| 乌拉特前旗| 丹巴县| 阳朔县| 开远市| 昌图县| 泰安市| 罗定市| 玛曲县| 佛学| 南充市| 大埔县| 建湖县| 辽源市| 高雄县| 竹山县| 垫江县| 繁峙县| 调兵山市| 祁阳县| 唐河县|