web-dev-qa-db-fra.com

SQL - sélectionne uniquement sur une colonne

J'ai cherché loin pour une réponse à ce problème. J'utilise un serveur Microsoft SQL, supposons que j'ai une table qui ressemble à ceci:

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

Je souhaite effectuer une requête qui sélectionne uniquement la colonne unique 'NUMBER' (que ce soit la première ou la dernière ligne ne me dérange pas). Donc cela me donnerait:

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

Comment est-ce réalisable?

39
Jason Lipo

Comme vous ne vous en souciez pas, j'ai choisi l'identifiant maximal pour chaque numéro.

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

explication de la requête

 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

Une approche très typique de ce type de problème consiste à utiliser row_number():

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

Ceci est plus généralisable que d'utiliser une comparaison avec l'id minimum. Par exemple, vous pouvez obtenir une ligne aléatoire en utilisant order by newid(). Vous pouvez sélectionner 2 lignes en utilisant where seqnum <= 2.

52
Gordon Linoff

Vous allez utiliser la requête suivante:

SELECT * FROM [table] GROUP BY NUMBER;

[table] est le nom de la table.

Ceci fournit une liste unique pour la colonne NUMBER, mais les autres colonnes peuvent être dépourvues de sens en fonction de l'implémentation du fournisseur. c'est-à-dire qu'ils peuvent ne pas correspondre ensemble à une ligne ou à des lignes spécifiques.

0
Gedalya