2016-06-17 4 views
1

zu verwenden, ich habe versucht, andere Antworten für Alter ohne Erfolg hier anzupassen, geht so hier ... Ich habe eine grundlegende Abfrage:Wie TOP N WITH TIES neben COUNT

SELECT 
    * 
FROM 
    @tbl_counts 
ORDER BY 
    sgId, 
    CategoryCount DESC, 
    qccId; 

Dies zeigt die folgende

Für jeden eindeutigen sgId Wert, zeigen die Top-3 CategoryCount Werte (mit Verbindungen, wenn sie exis: Ergebnisse: die folgenden zeigen

sgId qccId CategoryCount 
------- -------- ------------- 
4668 18  8 
4668 77  7 
4668 2   6 
4669 43  2 
4669 46  2 
4670 25  3 
4670 27  3 
4670 74  2 
4671 56  4 
4671 60  3 
4671 74  3 
4671 54  3 
4671 55  3 
4671 78  2 
4671 88  1 
4671 89  1 
4671 90  3 

ich brauche diese Abfrage zu ändern t) und der entsprechende Wert qccId. Daher sollten die Ergebnisse sein:

sgId qccId CategoryCount 
------- ----- ------------- 
4668 18 8 
4668 77 7 
4668 2  6  -- top 3 4668 
4669 43 2  
4669 46 2  -- top 2 4669 because only 2 existed 
4670 25 3  
4670 27 3  
4670 74 2  -- top 3 4670 
4671 56 4  
4671 60 3  
4671 74 3  
4671 54 3  
4671 55 3  -- top 5 4671 caused by TIES, but discards others 

Normalerweise würde ich ROW_NUMBER hier, aber kämpfen bin, weil es nicht vorhanden TIES tut (ich glaube nicht). Daher sind andere Antworten auf die Anpassung ich gefunden habe, habe ich so weit gekommen, aber es funktioniert nicht richtig ...

SELECT 
    cnt.* 
FROM 
    (
    SELECT DISTINCT 
     sgId 
    FROM 
     @tbl_counts) sg INNER JOIN 
    (
    SELECT TOP 3 WITH TIES 
     * 
    FROM 
     @tbl_counts 
    ORDER BY 
     CategoryCount DESC) cnt ON cnt.sgId = sg.sgId 

Antwort

2

sehen aus wie die perfekte Job für die Fensterfunktion DENSE_RANK:

;WITH 
    cte AS 
    (
     SELECT  *, 
        DENSE_RANK() OVER (PARTITION BY sgId ORDER BY CategoryCount DESC) As RowRank 
     FROM  @tbl_counts 
    ) 

SELECT  * 
FROM  cte 
WHERE  RowRank <= 3 
ORDER BY sgId, CategoryCount DESC, qccId 
+0

Wow. Ich wusste nicht einmal, dass das existiert. Klappt wunderbar. Ich bin unterwegs, um die Dokumentation zu studieren, aber für andere, dies fasst zusammen, wie erstaunlich das hier ist https://blog.jooq.org/2014/08/12/the-difference-between-row_number-rank-and-dense_rank/ Vielen Dank :-) – EvilDr

0

Sie könnten TOP 1 WITH TIES verwenden, wie Sie in Titel vorgeschlagen:

SELECT TOP 1 WITH TIES * 
FROM @tbl_counts 
ORDER BY 
    IIF(DENSE_RANK() OVER(PARTITION BY sgId ORDER BY CategoryCount DESC)<=3,0,1); 

LiveDemo