2013-07-24 31 views
6

我搜索了很多,但沒有找到適合我的問題的解決方案。SQL GROUP_CONCAT分爲不同的列

我想要做什麼?

我在MySQL 2個表: - 國家 - 外幣 (我通過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()這樣的函數,但這不起作用。

+0

SQL不支持動態數量的列。您將不得不在應用程序中執行此操作。 – Vatev

+0

您可以使用光標中的邏輯來執行此操作。但遊標首先必須查看結果集需要多少列數據。動態地創建一個臨時表來填充和稍後選擇。動態的列數是這個挑戰的問題。 –

回答

6

你可以用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查詢返回一組明確定義的列。查詢不能有可變數量的列(除非通過prepare語句使用動態SQL)。

+0

@Luv。 。 。我很抱歉。我沒有看到問題中的SQLFiddle鏈接。上面的代碼已經過測試和工作。 –

+0

完美的作品!感謝您的快速和非常正確的答案!我會接受它,因爲時限已經結束,答案是一些:p –

-2

YPU可以使用動態SQL,但你將不得不使用過程

1

使用此查詢制定貨幣列數,你需要:

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) 

然後動態地創建和執行prepared statement生成結果,使用上面的查詢結果Gordon Linoff解決方案在此線程中。