2013-12-05 7 views
35

Я искал широкий и широкий ответ на эту проблему. Я использую Microsoft SQL Server, предположим, что у меня есть таблица, которая выглядит следующим образом:SQL - выберите только один столбец

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

Я хочу, чтобы выполнить один запрос, который только выбирает уникальный столбец «NUMBER» (является ли быть первой или последней строки меня не беспокоит). Так это дало бы мне:

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

Как это достижимо?

+0

Это не совсем понятно, что вы хотите. Вы хотите один ряд (как вы спросили) или два (например, ваш второй блок кода)? Или это действительно одно число * за страну *? – ashes999

+0

Вы действительно искали «далеко и широко» для этого? Это довольно распространенный запрос. –

+1

Также дубликат http://stackoverflow.com/questions/966176/select-distinct-on-one-column?rq=1 ... и http://stackoverflow.com/questions/5021693/distinct-for- only-one-column? lq = 1 ... и http://stackoverflow.com/questions/1785634/select-distinct-on-one-column-return-multiple-other-columns-sql-server?lq=1 ... –

ответ

34

Поскольку вам все равно, я выбрал максимальный идентификатор для каждого номера.

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

Запрос Объяснение

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 
+2

Так или иначе, я не проголосовал за это, но а потому, что самосоединение с совокупностью против одной таблицы становится экспоненциально более дорогим (с точки зрения чтения) по мере увеличения таблицы. [Ответ Гордона] (http://stackoverflow.com/a/20406419/61305), помимо того, что он более гибкий, также более эффективен (или, по крайней мере, не хуже). –

+3

Не стоит ли дороже полиномиально? Как вы получаете «экспоненциально»? – Anon

+0

Я ответил сначала, а потом было прозрение. Во всяком случае, я проголосовал за ответ Гордона, так как большинство дубликатов используют один и тот же метод окон. –

0

Вы будете использовать следующий запрос:

SELECT * FROM [table] GROUP BY NUMBER; 

Где [table] это имя таблицы.

Это обеспечивает уникальный список для столбца NUMBER, однако другие столбцы могут быть бессмысленными в зависимости от реализации поставщика; то есть они могут не совпадать с конкретными строками или строками.

+6

@Gedalya Это возможно только в MySQL.Он вернет ошибку в SQL-сервере. – sahalMoidu

52

Очень типичный подход к этому типу проблемы заключается в использовании row_number():

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

Это более обобщенное, чем при использовании сравнения с минимальным идентификатором. Например, вы можете получить случайную строку, используя order by newid(). Вы можете выбрать 2 строки, используя where seqnum <= 2.

Смежные вопросы