Wählen Sie eindeutige Zeilen basierend auf einer einzelnen Spalte aus


71

Ich möchte Zeilen mit einem auswählen distinct email, siehe folgende Beispieltabelle:

+----+---------+-------------------+-------------+
| id | title   | email             | commentname |
+----+---------+-------------------+-------------+
|  3 | test    | rob@hotmail.com   | rob         |
|  4 | i agree | rob@hotmail.com   | rob         |
|  5 | its ok  | rob@hotmail.com   | rob         |
|  6 | hey     | rob@hotmail.com   | rob         |
|  7 | nice!   | simon@hotmail.com | simon       |
|  8 | yeah    | john@hotmail.com  | john        |
+----+---------+-------------------+-------------+

Das gewünschte Ergebnis wäre:

+----+-------+-------------------+-------------+
| id | title | email             | commentname |
+----+-------+-------------------+-------------+
|  3 | test  | rob@hotmail.com   | rob         |
|  7 | nice! | simon@hotmail.com | simon       |
|  8 | yeah  | john@hotmail.com  | john        |
+----+-------+-------------------+-------------+

Wo es mir egal ist, welcher idSpaltenwert zurückgegeben wird. Was wäre das erforderliche SQL?

Antworten:


97

Schnelle in TSQL

SELECT a.*
FROM emails a
INNER JOIN 
  (SELECT email,
    MIN(id) as id
  FROM emails 
  GROUP BY email 
) AS b
  ON a.email = b.email 
  AND a.id = b.id;

1
Wow, das war schnell, Leute! :) Die Antwort des Laptops war die kürzeste und einfachste, danke!
Flo

8
Das distinctSchlüsselwort ist hier nicht erforderlich. Außerdem scheint es so, als würde ein Join-On idauch den Trick machen.
Adam Robinson

Ich habe eine riesige Tabelle mit Primärschlüssel, ein Aggregat aus zwei Spalten, es funktioniert in diesem Fall nicht
AurA

@downvoter, was meinst du mit nicht arbeiten, wird vielleicht eine andere Frage sein?
Turbot

2
Ausgezeichnet, ich habe die min auf max geändert, um die letzte Zeile im Duplikat anstelle der ersten zu erhalten
Mian Asbat Ahmad

34

Ich nehme an, Sie meinen , dass Sie kümmern sich nicht , welche Zeile die zu erhalten , verwendet wird title, idund commentnameWerte (Sie „rauben“ für alle Zeilen haben, aber ich weiß nicht , ob das etwas ist eigentlich, die durchgesetzt werden würde oder nicht in Ihrem Datenmodell). Wenn ja, können Sie Fensterfunktionen verwenden, um die erste Zeile für eine bestimmte E-Mail-Adresse zurückzugeben:

select
    id,
    title,
    email,
    commentname

from
(
select 
    *, 
    row_number() over (partition by email order by id) as RowNbr 

from YourTable
) source

where RowNbr = 1

2
Dies ist die beste Lösung, da sie auf doppelte Zeilen angewendet werden kann, die keine eindeutige Identitätsspalte haben, oder auf solche, die dies tun.
Antony Booth

.... Ja, dies löste das Problem für mich .... Die obige Lösung gruppierte nur die Tabellendaten ..... dh für Microsoft SQL 2008 Server / Daten ......... danke Adam .. ....
Siwoku Adeola

4

Wenn Sie MySql 5.7 oder höher verwenden , können wir gemäß diesen Links ( MySql Official , SO QA ) einen Datensatz pro Datensatz auswählen, group byohne dass Aggregatfunktionen erforderlich sind.

Damit kann die Abfrage vereinfacht werden.

select * from comments_table group by commentname;

Probieren Sie die Abfrage hier in Aktion aus


Leider ist die Frage mit tsql und sqlserver markiert.
Starwed

1
Obwohl es die richtige Antwort auf die falsche Frage war, bin ich hier gelandet und habe nach dieser Lösung für MySQL
gesucht.

1
Schöne Lösung verdient mehr Respekt
Kai Wang

2

Da es Ihnen egal ist, welche ID zurückgegeben werden soll, bleibe ich bei der MAX-ID für jede E-Mail, um die SQL-Abfrage zu vereinfachen. Probieren Sie es aus

;WITH ue(id)
 AS
 (
   SELECT MAX(id)
   FROM table
   GROUP BY email
 )
 SELECT * FROM table t
 INNER JOIN ue ON ue.id = t.id
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.