2016-07-14 9 views
-1

Gibt es eine Möglichkeit, diese Art der AbfrageSql: Distinct Klausel mit dynamischer Ordnung von

laufen
select distinct ri.id, r.RequestDate, count(ri.id) over() as TotalRecords 
    from security.RequestItemView ri 
    order by r.RequestDate asc 
     case when @SortColumn='RequestDate' and @SortOrder='ASC' then r.RequestDate end asc, 
     case when @SortColumn='RequestDate' and @SortOrder='DESC' then r.RequestDate end desc 

Dynamische order by Klausel funktioniert gut, bis ich distinct-Klausel verwenden, gibt es diesen Fehler, wenn ich verschiedene verwenden

ORDER BY-Elemente müssen in der Auswahlliste erscheinen, wenn SELECT DISTINCT angegeben ist.

Ich weiß, dass wir die Spalte in der Auswahlliste haben müssen, die durch Klausel verwendet wird, um, und das ist, warum ich r.RequestDate Spalte bin Auswahl, ich will eigentlich nicht, dass die Spalte auszuwählen, sondern distict Arbeit, die mich machen wähle es aus, aber es funktioniert immer noch nicht.

Wenn ich ersetzen dynamische Ordnung mit festen Reihenfolge wie folgt

order by r.RequestDate asc

es zu arbeiten beginnt, so dass im Grunde dynamische order by und distinct Klausel zusammen funktioniert nicht.

Jeder Weg, dies zu erreichen?

+0

Sind Sie sicher, dass der Wert "count" für Sie sinnvoll ist? "über nichts" bedeutet den gleichen Wert in jeder Zeile. –

+0

@IvanStarostin. . . Dies ist eine ausgefallene (und ich denke ineffiziente) Art, eine Aggregation zu machen. –

Antwort

1

können Sie Aggregation anstelle von distinct:

select ri.id, r.RequestDate, count(ri.id) as TotalRecords 
from security.RequestItemView ri 
group by ri.id, r.RequestDate 
order by (case when @SortColumn = 'RequestDate' and @SortOrder='ASC' then min(r.RequestDate) end) asc, 
     (case when @SortColumn = 'RequestDate' and @SortOrder='DESC' then min(r.RequestDate) end) desc; 
+0

Danke! Gibt es Leistungsunterschiede in 'distinct' und' group by'? –

+0

Ich denke, dass die Optimierung manchmal andere Algorithmen wählen kann, so dass es einen Unterschied geben könnte. Aber im Allgemeinen sind sie gleichwertig. –

0

Gordon eine große Idee hatte, aber distinct gelten nach der analytischen Zahl berechnet wird. (Ich habe nach einer autoritativen Quelle gesucht und keine gefunden. Es ergibt jedoch einen Sinn.) Wenn Sie danach suchen, dann sollten Sie diese Summen überprüfen. Siehe nachstehendes Beispiel:

create table T (n int); 
insert into T (n) values (1), (1); 

select distinct n, count(n) from T; -- returns 2 
select n, count(n) over() from T group by n; -- returns 1 

http://rextester.com/SSI28665

Ich denke, die einfachste Lösung ist es in einem Tabellenausdruck einpacken:

select id, RequestDate, TotalRecords from (
    select distinct 
     ri.id, r.RequestDate, count(ri.id) over() as TotalRecords 
     case when @SortColumn = 'RequestDate' and @SortOrder = 'ASC' 
      then r.RequestDate end as sort1, 
     case when @SortColumn = 'RequestDate' and @SortOrder = 'DESC' 
      then r.RequestDate end as sort2 
    from security.RequestItemView ri 
) as S 
order by sort1 asc, sort2 desc; 

Natürlich gibt es Potenzial ist für die neuen Spalten zu stören Unterscheidbarkeit. In diesem Fall fügen Sie in die Ausgabe bereits RequestDate ein, sodass die Anzahl der Zeilen nicht erhöht wird. Da Sie eine Variable @SortColumn haben, vermute ich, dass die von Ihnen gepostete Abfrage nicht die größeren Ergebnisse widerspiegelt, mit denen Sie tatsächlich arbeiten, und der Grund, warum ich diesen Vorbehalt notiere.