SQL GROUP CONCAT разбивается на разные столбцы

Я много искал, но не нашел правильного решения моей проблемы.

что я хочу сделать?

у меня есть 2 таблицы в MySQL: - Страна - Валюта (Я соединяю их вместе через CountryCurrency --> из-за многих отношений)

см. это для рабочего примера:http://sqlfiddle.com#!2 / 317d3/8/0

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

Я нашел функцию group_concat:

SELECT country.Name, country.ISOCode_2, group_concat(currency.name) AS currency
FROM country
INNER JOIN countryCurrency ON country.country_id = countryCurrency.country_id
INNER JOIN currency ON currency.currency_id = countryCurrency.currency_id
GROUP BY country.name

это имеет следующий результат:

NAME            ISOCODE_2   CURRENCY

Afghanistan AF          Afghani
Åland Islands   AX          Euro
Albania         AL          Lek
Algeria         DZ          Algerian Dinar
American Samoa  AS          US Dollar,Kwanza,East Caribbean Dollar

но теперь я хочу разделить валюты в разных столбцах (валюта 1, валюта 2,...). Я уже пробовал такие функции, как MAKE_SET (), но это не работает.

3 ответов


вы можете сделать это с помощью substring_index(). Следующий запрос использует ваш как подзапрос, а затем применяет эту логику:

select Name, ISOCode_2,
       substring_index(currencies, ',', 1) as Currency1,
       (case when numc >= 2 then substring_index(substring_index(currencies, ',', 2), ',', -1) end) as Currency2,
       (case when numc >= 3 then substring_index(substring_index(currencies, ',', 3), ',', -1) end)  as Currency3,
       (case when numc >= 4 then substring_index(substring_index(currencies, ',', 4), ',', -1) end)  as Currency4,
       (case when numc >= 5 then substring_index(substring_index(currencies, ',', 5), ',', -1) end)  as Currency5,
       (case when numc >= 6 then substring_index(substring_index(currencies, ',', 6), ',', -1) end)  as Currency6,
       (case when numc >= 7 then substring_index(substring_index(currencies, ',', 7), ',', -1) end)  as Currency7,
       (case when numc >= 8 then substring_index(substring_index(currencies, ',', 8), ',', -1) end)  as Currency8
from (SELECT country.Name, country.ISOCode_2, group_concat(currency.name) AS currencies,
             count(*) as numc
      FROM country
      INNER JOIN countryCurrency ON country.country_id = countryCurrency.country_id
      INNER JOIN currency ON currency.currency_id = countryCurrency.currency_id
      GROUP BY country.name
     ) t

выражение substring_index(currencies, ',' 2) принимает список в валютах до второго. Для американских Somoa, что бы 'US Dollar,Kwanza'. Следующий звонок с -1 в качестве аргумента берет последний элемент списка, который будет 'Kwanza', который является вторым элементом currencies.

Также обратите внимание, что SQL-запросы возвращают четко определенный набор столбцов. Ля запрос не может иметь переменное количество столбцов (если вы используете динамический SQL через prepare заявления).


используйте этот запрос для определения количества столбцов валюты, которые вам понадобятся:

SELECT MAX(c) FROM 
((SELECT count(currency.name) AS c
FROM country
INNER JOIN countryCurrency ON country.country_id = countryCurrency.country_id
INNER JOIN currency ON currency.currency_id = countryCurrency.currency_id
GROUP BY country.name) as t)

затем динамически создавать и выполнять подготовленное заявление чтобы сгенерировать результат, используя решение Gordon Linoff с результатом запроса выше в этом потоке.


Ypu может использовать динамический SQL, но вам придется использовать процедуру