Запрос MySQL с ключевым словом DISTINCT

Моя таблица MySQL country_phone_codes выглядит примерно так:

id country_code area_code name ------------------------------------------------------------ 1 | 93 | 93 | AFGHANISTAN 2 | 93 | 9370 | AFGHANISTAN - MOBILE 3 | 93 | 9375 | AFGHANISTAN - MOBILE 4 | 355 | 355 | ALBANIA 5 | 355 | 35568 | ALBANIA - MOBILE - AMC 6 | 213 | 213 | ALGERIA 7 | 213 | 2131 | ALGERIA - CAT ------------------------------------------------------------ 

Это всего лишь несколько записей из более чем 28000 записей. Я пытаюсь сформулировать запрос, который предоставит мне результат, подобный этому,

 country_code name ----------------------------- 93 | AFGHANISTAN 355 | ALBANIA 213 | ALGERIA ----------------------------- 

Используя SELECT DISTINCT(country_code) FROM country_phone_codes ORDER BY country_code LIMIT 0,260 , я могу получить разные коды стран. Но как мне получить соответствующее название страны?

Ответ тривиален, используя GROUP BY :

 SELECT country_code,MIN(name) FROM country_phone_codes GROUP BY country_code; 

Функция DISTINCT и ORDER BY не нужны с GROUP BY . Поскольку исходный вопрос, конкретно относящийся к MySQL, функция агрегации MIN() не требуется, и вы можете увидеть более высокую производительность без нее, если выполняются все следующие условия:

  • Сервер – это MySQL
  • Механизм хранения – InnoDB
  • Первый столбец данных примера является первичным ключом, и записи следуют тому же порядку, предложенному небольшим образцом, а именно название страны появляется перед всеми другими именами в группе.

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

Чтобы выбрать отдельный country_code, пары имен:

 select country_code, name from country_phone_codes where country_code = area_code; 

Поскольку вам кажется, что вы хотите выбрать эти строки, где area_code совпадает с country_code, вы можете просто выбрать те строки, где area_code и country_code равны:

 SELECT country_code, name FROM country_phone_codes WHERE area_code = country_code; 

Если есть вероятность, что существует несколько строк с одним и тем же кодом области и кодом страны, вы можете использовать DISTINCT для выбора только одной строки для каждого (country_code, name) кортежа.

 SELECT DISTINCT country_code, name FROM country_phone_codes WHERE area_code = country_code; 

Похоже, у вас есть отношения «один ко многим» между country_code и именем.

Если вы выполните простой запрос GROUP BY, например

 SELECT country_code,name FROM country_phone_codes GROUP BY country_code 

вы можете

 country_code name ----------------------------- 93 | AFGHANISTAN 355 | ALBANIA 213 | ALGERIA 124 | COUNTRY - MOBILE ----------------------------- 

предполагая, что все названия вашей страны

 COUNTRY COUNTRY - SOMETHING COUNTRY - SOMETHING - SOMETHING 

было бы лучше использовать

 SELECT country_code,MIN(name) FROM country_phone_codes GROUP BY country_code 

так что в итоге

 country_code name ----------------------------- 93 | AFGHANISTAN 355 | ALBANIA 213 | ALGERIA xxx | COUNTRY ----------------------------- 

это предполагает, что у вас есть обе записи в вашей таблице

 id country_code area_code name ------------------------------------------------------------ xx | xxx | xx | COUNTRY xx | xxx | xx | COUNTRY - SOMETHING ------------------------------------------------------------ 

Вам также нужно сгруппировать свой country_code, а затем только вы получите правильные результаты сопоставления.

 SELECT country_code,name FROM country_phone_codes group by country_code ORDER BY country_code 

И нам нужно избегать использования Distinct в select, поскольку это дает проблемы с производительностью. Вместо этого мы можем использовать group by