亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解析針對distinct疑問引發的問題

發布時間:2021-11-29 11:28:13 來源:億速云 閱讀:113 作者:柒染 欄目:數據庫

如何解析針對distinct疑問引發的問題,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

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

假設有如下這樣一張表格:

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

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

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

select distinct name from Sample order by DepartmentId

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

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

select distinct name,DepartmentId from Sample order by DepartmentId

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

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

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

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

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

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

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

SQL Server 2005開始提供了一個ROW_NUMBER的功能,結合這個功能,我實現了下面這樣的查詢:

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

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

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

關于如何解析針對distinct疑問引發的問題問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

厦门市| 襄城县| 龙州县| 淮阳县| 辛集市| 昭觉县| 桂阳县| 扎兰屯市| 萨迦县| 南川市| 沂水县| 遵化市| 石棉县| 奉贤区| 孟津县| 丰顺县| 天津市| 莱阳市| 宜宾市| 巧家县| 馆陶县| 松桃| 裕民县| 河曲县| 墨江| 西藏| 罗甸县| 阜康市| 盐池县| 保山市| 南溪县| 余江县| 吴桥县| 囊谦县| 普安县| 兴和县| 呼玛县| 延川县| 师宗县| 青田县| 正安县|