針對distinct疑問激發的一系列思慮。本站提示廣大學習愛好者:(針對distinct疑問激發的一系列思慮)文章只能為提供參考,不一定能成為您想要的結果。以下是針對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.Name FROM (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 percent Name,DepartmentId,ROW_NUMBER() over(partition by name order by departmentid) row from Sample order by DepartmentId) a where a.row=1 order by a.DepartmentId
然後,我獲得了上面如許的成果,我斟酌上去,這應當是相符了之條件到的這個需求的
比擬較而言,這個查詢的效力會低一些,這個是可以預感的(可以經由過程下圖看出一點眉目)。但假如需求是硬性的,那末就義一些機能也是不奇異的。固然,我們可以再研討看看能否有更優的一些寫法。不管若何,應用內置尺度的完成,平日都是絕對較快的。
以上就是關於distinct疑問激發的一系列思慮,願望對年夜家的進修有所贊助。