2013-07-24 38 views
6

Çok arandım, ancak sorunuma uygun bir çözüm bulamadım.SQL GROUP_CONCAT farklı sütunlara bölünmüş

Ne yapmak isterim?

Ben MySQL 2 tablo vardır: - Ülke - Döviz -

çalışan bir örneğin bu Bkz (I CountryCurrency aracılığıyla onları bir araya> nedeniyle birçok ilişki birçok): http://sqlfiddle.com/#!2/317d3/8/0

Her iki tabloyu bir birleştirme kullanarak birbirine bağlamak istiyorum, ancak ülke başına yalnızca bir satır göstermek istiyorum (bazı ülkelerin birden çok para birimi vardır, bu nedenle ilk sorun buydu).

Ben group_concat işlevini bulundu:

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 

Bu aşağıdaki sonucu vardır:

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 

Ama benim şimdi istiyorum para 2 farklı sütunlarda para (para birimi 1, bölmek olduğunu ...). Zaten MAKE_SET() gibi fonksiyonları denedim ama bu işe yaramıyor.

+0

SQL, dinamik bir sütun sayısını desteklemiyor. Uygulamada bunu yapmak zorunda kalacaksınız. – Vatev

+0

Bunu yapmak için İmleç'te mantığı kullanabilirsiniz. Ancak, imleç ilk önce sonuç kümenizin kaç tane veri sütununa ihtiyaç duyduğunu incelemeliydi. Dinamik olarak doldurulacak ve daha sonra seçilecek bir geçici tablo oluşturun. Bu zorlukla ilgili sorun, dinamik bir sütun sayısıdır. –

cevap

6

Bunu substring_index() ile yapabilirsiniz. Aşağıdaki sorgu alt sorgu olarak seninkini kullanır ve sonra bu mantığı geçerlidir:

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 

ifadesi substring_index(currencies, ',' 2) ikincisi kadar para listesini alır. Amerikan Somoa için, bu 'US Dollar,Kwanza' olurdu. Argüman olarak -1 ile yapılan sonraki çağrı, listenin son elemanını alır, bu'un ikinci öğesi olan 'Kwanza' olur.

Ayrıca, SQL sorgularının iyi tanımlanmış bir sütun kümesini döndürdüğünü de unutmayın. Bir sorgu, değişken bir sütun sayısına sahip olamaz (bir prepare bildirimi aracılığıyla dinamik SQL kullanmıyorsanız).

+0

@Luv. . . Özür dilerim. Sorgudaki SQLFiddle bağlantısını görmedim. Yukarıdaki kod test edilmiş ve çalışır. –

+0

Mükemmel çalışıyor! Hızlı ve doğru cevap için teşekkürler! Bir cevap olarak kabul edeceğim zaman sınırı bittiği için: p –

-2

ihtiyacınız koyulabilmesi dinamik SQL kullanabilirsiniz, ancak para sütun sayısını atlatmanın prosedürünü

1

kullanılması, bu sorgu kullanmak zorunda olacak:

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) 

Sonra dinamik oluşturmak ve prepared statement yürütmek Bu iş parçacığı için yukarıdaki sorgu sonucu ile Gordon Linoff çözümünü kullanarak, sonuç üretmek için.

İlgili konular