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.