it-swarm.com.de

SQL - Nur in einer Spalte eindeutig auswählen

Ich habe weit und breit nach einer Antwort auf dieses Problem gesucht. Ich verwende einen Microsoft SQL Server. Angenommen, ich habe eine Tabelle, die so aussieht:

+--------+---------+-------------+-------------+
| ID     | NUMBER  | COUNTRY     | LANG        |
+--------+---------+-------------+-------------+
| 1      | 3968    | UK          | English     |
| 2      | 3968    | Spain       | Spanish     |
| 3      | 3968    | USA         | English     |
| 4      | 1234    | Greece      | Greek       |
| 5      | 1234    | Italy       | Italian     |

Ich möchte eine Abfrage durchführen, bei der nur die eindeutige Spalte 'NUMBER' ausgewählt wird (ob es sich um die erste oder die letzte Zeile handelt, stört mich nicht). Das würde mir also geben:

+--------+---------+-------------+-------------+
| ID     | NUMBER  | COUNTRY     | LANG        |
+--------+---------+-------------+-------------+
| 1      | 3968    | UK          | English     |
| 4      | 1234    | Greece      | Greek       |

Wie ist das erreichbar?

39
Jason Lipo

Da es Ihnen egal ist, habe ich die maximale ID für jede Nummer gewählt.

select tbl.* from tbl
inner join (
select max(id) as maxID, number from tbl group by number) maxID
on maxID.maxID = tbl.id

Abfrageerklärung

 select 
    tbl.*  -- give me all the data from the base table (tbl) 
 from 
    tbl    
    inner join (  -- only return rows in tbl which match this subquery
        select 
            max(id) as maxID -- MAX (ie distinct) ID per GROUP BY below
        from 
            tbl 
        group by 
            NUMBER            -- how to group rows for the MAX aggregation
    ) maxID
        on maxID.maxID = tbl.id -- join condition ie only return rows in tbl 
                                -- whose ID is also a MAX ID for a given NUMBER
34
Kyle Hale

Ein sehr typischer Ansatz für diese Art von Problem ist die Verwendung von row_number():

select t.*
from (select t.*,
             row_number() over (partition by number order by id) as seqnum
      from t
     ) t
where seqnum = 1;

Dies ist verallgemeinerbarer als ein Vergleich mit der minimalen ID. Beispielsweise können Sie mit order by newid() eine zufällige Zeile abrufen. Sie können 2 Zeilen mit where seqnum <= 2 Auswählen.

52
Gordon Linoff

Sie werden die folgende Abfrage verwenden:

SELECT * FROM [table] GROUP BY NUMBER;

Woher [table] ist der Name der Tabelle.

Dies bietet eine eindeutige Auflistung für die Spalte NUMBER, die anderen Spalten können jedoch je nach Herstellerimplementierung bedeutungslos sein. Dies bedeutet, dass sie möglicherweise nicht zusammen einer bestimmten Zeile oder bestimmten Zeilen entsprechen.

0
Gedalya