{"id":158,"date":"2006-08-13T12:59:43","date_gmt":"2006-08-13T10:59:43","guid":{"rendered":"http:\/\/www.glorf.it\/blog\/2006\/08\/13\/sql-talk\/mssql2005-ranking-functions"},"modified":"2006-08-13T12:59:43","modified_gmt":"2006-08-13T10:59:43","slug":"mssql2005-ranking-functions","status":"publish","type":"post","link":"http:\/\/www.glorf.it\/blog\/2006\/08\/13\/sql-talk\/mssql2005-ranking-functions","title":{"rendered":"MSSQL2005: Ranking Functions"},"content":{"rendered":"<p>Etwas das mir beim Microsoft SQL Server 2005 besonders gut gef&#228;llt, sind die Ranking-Functions: row_number, rank, dense_rank und ntile:<br \/>\n<img decoding=\"async\" id=\"image157\" src=\"http:\/\/www.glorf.it\/blog\/wp-content\/uploads\/2006\/08\/ranking_results.png\" alt=\"Ranking-Functions\" \/><\/p>\n<p>Hier ein Aufrufbespiel:<\/p>\n<p><code lang=\"sql\">SELECT OrderID, Quantity,<br \/>\n\t\trow_number()\tOVER (ORDER BY quantity) AS &quot;row_number()&quot;,<br \/>\n\t\trank()\t\t\tOVER (ORDER BY quantity) AS &quot;rank()&quot;,<br \/>\n\t\tdense_rank()\tOVER (ORDER BY quantity) AS &quot;dense_rank()&quot;,<br \/>\n\t\tntile(10)\t\tOVER (ORDER BY quantity) AS &quot;ntile(10)&quot;<br \/>\n\tFROM Northwind.dbo.&quot;Order Details&quot;<br \/>\n\tWHERE ProductID=1<br \/>\n\tORDER BY Quantity<\/code><\/p>\n<p><em>row_number<\/em> liefert eine Nummerierung. Dabei muss man aber beachten, dass die Nummerierung nur dann eindeutig reproduzierbar ist, wenn die Sortierung pr&#228;zise ist. Im obigen Beispiel kann es mehrere Order-Details mit der gleichen Anzahl  geben. Deswegen ist die Row_Number hier &quot;nicht deterministisch&quot;, sondrn k&#246;nnte beim n&#228;chsten Aufruf anders Lauten. Die Abhilfe ist ganz einfach: Die Order-BY so erweitern, dass sie eindeutig ist.<\/p>\n<p><em>ntile(n)<\/em> verteilt die Datens&#228;tze gleichm&#228;&#223;ig in n T&#246;pfe. Die T&#246;pfe werden dabei nummeriert. Die Reihenfolge basiert intern auf der Row_Numer. Deswegen ist es auch bei NTile von der genauen Sortierung abh&#228;ngig, ob die Werte deterministisch sind oder nicht. Die T&#246;pfe werden dabei immer reihum aufgef&#252;llt, d.h. die vorderen T&#246;pfe haben in der Regel ein Mitglieder mehr als die hinteren.<\/p>\n<p><em>rank<\/em> liefert den Rang, wie bei den olympischen Spielen: Wenn zwei den gleichen Werte haben, dann teilen sie sich den ersten Platz und der n&#228;chste sitzt auch Platz 3. Rank ist deswegen immer deterministisch.<\/p>\n<p><em>dense_rank<\/em> liefert den Rang, ohne L&#252;cken. Auch diese Funktion ist immer deterministisch.<\/p>\n<p>Wer sie noch nicht kennt, dem w&#252;rde ich sie sehr ans Herz legen. Vertiefende Infos, insbesondere zu den Alternativen am Microsoft Sql Server 2000 werden in folgenden <a href=\"http:\/\/www.devweek.com\/code\/ben-gan-tsql-enhancements2006.zip\" target=\"_blank\">Beispielen von Itzik Ben-Gan<\/a> besonders gut beschrieben (in den Beispielen nach &quot;Rank&quot; suchen, sie sind gut kommentiert).<br \/>\nF&#252;r die Vertiefung empfehle ich den Einsatz mit Partitions (in Gruppen durchz&#228;hlen). <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Etwas das mir beim Microsoft SQL Server 2005 besonders gut gef&#228;llt, sind die Ranking-Functions: row_number, rank, dense_rank und ntile: Hier ein Aufrufbespiel: SELECT OrderID, Quantity, row_number() OVER (ORDER BY quantity) AS &quot;row_number()&quot;, rank() OVER (ORDER BY quantity) AS &quot;rank()&quot;, dense_rank() OVER (ORDER BY quantity) AS &quot;dense_rank()&quot;, ntile(10) OVER (ORDER BY quantity) AS &quot;ntile(10)&quot; FROM Northwind.dbo.&quot;Order [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/158"}],"collection":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/comments?post=158"}],"version-history":[{"count":0,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/158\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/media?parent=158"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/categories?post=158"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/tags?post=158"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}