Запрос SQL для возврата одной записи для каждого уникального значения в столбце - PullRequest
8 голосов
/ 11 июня 2009

У меня есть таблица в SQL Server 2000, которую я пытаюсь запросить особым образом. Лучший способ показать это на примере данных.

Вот, [Addresses]:

Name         Street                 City          State
--------------------------------------------------------
Bob          123 Fake Street        Peoria        IL
Bob          234 Other Street       Fargo         ND
Jim          345 Main Street        St Louis      MO

На самом деле это упрощенный пример структуры фактической таблицы. Структура таблицы полностью вне моего контроля. Мне нужен запрос, который будет возвращать один адрес на имя. Неважно, какой адрес, просто есть только один. Результат может быть таким:

Name         Street                 City          State
--------------------------------------------------------
Bob          123 Fake Street        Peoria        IL
Jim          345 Main Street        St Louis      MO

Я нашел похожий вопрос здесь , но ни одно из приведенных решений не работает в моем случае, потому что у меня нет доступа к CROSS APPLY, а вызов MIN() для каждого столбца будет смешивать разные адреса вместе и хотя мне все равно, какая запись возвращается, это должна быть одна целая строка, а не смесь разных строк.

Рекомендации по изменению структуры таблицы мне не помогут. Я согласен, что эта таблица ужасна (она хуже, чем показано здесь), но это часть основной базы данных ERP, которую я не могу изменить.

В этой таблице около 3000 записей. Первичного ключа нет.

Есть идеи?

Ответы [ 14 ]

0 голосов
/ 11 июня 2009
SELECT name, street, address, state
FROM
 (SELECT name, street, address, state,
  DENSE_RANK() OVER (PARTITION BY name ORDER BY street DESC) AS r 
 FROM tbl) AS t
WHERE r = 1; 
0 голосов
/ 11 июня 2009
SELECT name,
       ( SELECT TOP 1 street, city, state
           FROM addresses b
          WHERE a.name = b.name )
  FROM addresses a
 GROUP BY name
0 голосов
/ 11 июня 2009

Я не думаю, что вы можете сделать это, учитывая ваши ограничения. Вы можете вытащить различные комбинации этих полей. Но если бы кто-то написал Бобу и Боббу с одного и того же адреса, у вас получилось бы две записи. [GIGO] Вы правы, что любая группировка (за исключением группировки по всем полям, эквивалентным DISTINCT) будет смешивать строки. Жаль, что у вас нет уникального идентификатора для каждого клиента.

Возможно, вы сможете вкладывать запросы друг в друга таким образом, чтобы выбрать первые 1 для каждого имени и объединить все из них вместе.

0 голосов
/ 11 июня 2009

Небольшая модификация вышеупомянутого должна работать.

SELECT Name, Street, City, State
FROM table t 
INNER JOIN (
     SELECT Name, MIN(Street) AS Street
     FROM table m
     GROUP BY Name
) x
   ON x.Name = t.Name AND x.Street = t.Street

Теперь это не будет работать, если у вас та же улица, но другая информация отличается (например, с опечатками).

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

SELECT Name, Street, City, State
FROM table t 
INNER JOIN (
     SELECT Name, MIN(Street + '|' + City  + '|' + State) AS key
     FROM table m
     GROUP BY Name
) x
   ON  x.Name = t.Name
   AND x.key = Street + '|' + City  + '|' + State
...