Frage Wie verwendet man DISTINCT und ORDER BY in derselben SELECT-Anweisung?


Nach dem Ausführen der folgenden Anweisung:

SELECT  Category  FROM MonitoringJob ORDER BY CreationDate DESC

Ich erhalte die folgenden Werte aus der Datenbank:

test3
test3
bildung
test4
test3
test2
test1

aber ich möchte, dass die Duplikate wie folgt entfernt werden:

bildung
test4
test3
test2
test1

Ich habe versucht, DISTINCT zu verwenden, aber es funktioniert nicht mit ORDER BY in einer Anweisung. Bitte helfen Sie.

Wichtig:

  1. Ich habe es versucht mit:

    SELECT DISTINCT Category FROM MonitoringJob ORDER BY CreationDate DESC
    

    es funktioniert nicht.

  2. Bestellung von CreationDate ist sehr wichtig.


75
2018-03-22 12:55


Ursprung


Antworten:


Das Problem ist, dass die Spalten in der verwendet werden ORDER BY sind nicht in der angegeben DISTINCT. Um dies zu tun, müssen Sie ein verwenden Aggregatfunktion sortieren und verwenden Sie a GROUP BY das machen DISTINCT Arbeit.

Versuchen Sie etwas wie folgt:

SELECT DISTINCT Category, MAX(CreationDate) 
FROM MonitoringJob 
GROUP BY Category 
ORDER BY MAX(CreationDate) DESC, Category

132
2018-03-22 13:01



Wenn die Ausgabe von MAX (CreationDate) nicht erwünscht ist - wie im Beispiel der ursprünglichen Frage - ist die einzige Antwort die zweite Aussage von Prashant Gupta's Antwort:

SELECT [Category] FROM [MonitoringJob] 
GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC

Erläuterung: Sie können die ORDER BY-Klausel nicht in einer Inline-Funktion verwenden, sodass die Anweisung in der Antwort von Prutswonder in diesem Fall nicht verwendet werden kann. Sie können keine äußere Auswahl einfügen und den MAX-Teil (CreationDate) verwerfen.


3
2017-11-30 11:08



Verwenden Sie einfach diesen Code, wenn Sie Werte für die Spalten [Kategorie] und [CreationDate] möchten

SELECT [Category], MAX([CreationDate]) FROM [MonitoringJob] 
             GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC

Oder verwenden Sie diesen Code, wenn Sie nur Werte der Spalte [Kategorie] möchten.

SELECT [Category] FROM [MonitoringJob] 
GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC

Sie werden alle eindeutigen Aufzeichnungen haben, was immer Sie wollen.


2
2018-01-30 06:46



2) Bestellung von CreationDate ist sehr wichtig

Die ursprünglichen Ergebnisse zeigten, dass "test3" mehrere Ergebnisse hatte ...

Es ist sehr einfach, MAX zu benutzen, um Duplikate in Group By zu entfernen ... und zu vergessen oder zu ignorieren, was die zugrunde liegende Frage ist ...

Das OP erkannte vermutlich, dass die Verwendung von MAX ihm das letzte "erstellt" gab und die Verwendung von MIN würde das erste "erschaffen" geben ...


1
2017-10-22 10:08



Erweiterte Sortierschlüsselspalten

Der Grund, warum was Sie nicht tun wollen, ist wegen der logische Reihenfolge der Operationen in SQL, die für Ihre erste Abfrage (vereinfacht) ist:

  • FROM MonitoringJob
  • SELECT Category, CreationDate d. h. ein so genanntes hinzufügen erweiterte Sortierschlüsselspalte
  • ORDER BY CreationDate DESC
  • SELECT Category d. h. entfernen Sie die erweiterte Sortierschlüsselspalte wieder von dem Ergebnis.

Also, dank dem SQL-Standard erweiterte Sortierschlüsselspalte Feature, ist es durchaus möglich, durch etwas zu bestellen, das nicht in der SELECT Klausel, weil es vorübergehend hinter den Kulissen hinzugefügt wird.

Also, warum funktioniert das nicht mit? DISTINCT?

Wenn wir das hinzufügen DISTINCT Operation würde es zwischen hinzugefügt werden SELECT und ORDER BY:

  • FROM MonitoringJob
  • SELECT Category, CreationDate
  • DISTINCT
  • ORDER BY CreationDate DESC
  • SELECT Category

Aber jetzt, mit dem erweiterte Sortierschlüsselspalte  CreationDate, die Semantik der DISTINCT Operation wurde geändert, so dass das Ergebnis nicht mehr das gleiche sein wird. Dies ist nicht das, was wir wollen, also verbieten sowohl der SQL-Standard als auch alle vernünftigen Datenbanken diese Verwendung.

Problemumgehungen

PostgreSQL hat die DISTINCT ON Syntax, die hier genau für diesen Job verwendet werden kann:

SELECT DISTINCT ON (CreationDate) Category 
FROM MonitoringJob 
ORDER BY CreationDate DESC

Es kann wie folgt mit der Standardsyntax emuliert werden

SELECT Category
FROM (
  SELECT Category, MAX(CreationDate) AS CreationDate
  FROM MonitoringJob
  GROUP BY Category
) t
ORDER BY CreationDate DESC

Oder einfach (in diesem Fall), wie auch von Prutswonder

SELECT Category, MAX(CreationDate) AS CreationDate
FROM MonitoringJob
GROUP BY Category
ORDER BY CreationDate DESC

Ich habe hier über SQL DISTINCT und ORDER BY mehr im Detail gebloggt.


1
2017-07-20 08:24



Distinct sortiert Datensätze in aufsteigender Reihenfolge. Wenn Sie in der Reihenfolge sortieren möchten, verwenden Sie:

SELECT DISTINCT Category
FROM MonitoringJob
ORDER BY Category DESC

Wenn Sie Datensätze basierend auf dem CreationDate-Feld sortieren möchten, muss dieses Feld in der Select-Anweisung enthalten sein:

SELECT DISTINCT Category, creationDate
FROM MonitoringJob
ORDER BY CreationDate DESC

0
2018-03-22 13:10



if object_id ('tempdb..#tempreport') is not null
begin  
drop table #tempreport
end 
create table #tempreport (
Category  nvarchar(510),
CreationDate smallint )
insert into #tempreport 
select distinct Category from MonitoringJob (nolock) 
select * from #tempreport  ORDER BY CreationDate DESC

0
2018-01-25 13:59