2013-07-24 55 views
6

Tôi đã tìm kiếm rất nhiều nhưng không tìm thấy giải pháp phù hợp cho vấn đề của mình.SQL GROUP_CONCAT được chia thành các cột khác nhau

Tôi muốn làm gì?

Tôi có 2 bảng trong MySQL: - Country - ngoại tệ (Tôi tham gia cùng họ với nhau thông qua CountryCurrency -> do nhiều mối quan hệ)

Xem này cho một ví dụ làm việc: http://sqlfiddle.com/#!2/317d3/8/0

Tôi muốn liên kết cả hai bảng với nhau bằng cách tham gia, nhưng tôi muốn chỉ hiển thị một hàng cho mỗi quốc gia (một số quốc gia có nhiều loại tiền tệ, vì vậy đó là vấn đề đầu tiên).

tôi thấy chức năng 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 

này có kết quả sau:

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 

Nhưng những gì tôi muốn bây giờ là để phân chia các loại tiền tệ trong các cột khác nhau (tiền tệ 1, tiền tệ 2, ...). Tôi đã thử các chức năng như MAKE_SET() nhưng điều này không hoạt động.

+0

SQL không hỗ trợ số lượng cột động. Bạn sẽ phải làm điều đó trong ứng dụng. – Vatev

+0

Bạn có thể sử dụng logic trong một con trỏ để làm điều này. Nhưng con trỏ đầu tiên sẽ phải xem xét bao nhiêu cột dữ liệu mà tập kết quả của bạn cần. Tự động tạo một bảng tạm thời để được điền và sau đó được chọn. Một số cột động lực là vấn đề với thử thách này. –

Trả lời

6

Bạn có thể thực hiện việc này với substring_index(). Các truy vấn sau đây sử dụng của bạn như một subquery và sau đó áp dụng logic này:

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 

Khái niệm substring_index(currencies, ',' 2) mất danh sách bằng ngoại tệ lên đến một giây. Đối với người Somoa của Mỹ, đó sẽ là 'US Dollar,Kwanza'. Cuộc gọi tiếp theo với số -1 làm đối số lấy phần tử cuối cùng của danh sách, là 'Kwanza', là phần tử thứ hai của currencies.

Cũng lưu ý rằng truy vấn SQL trả về một tập hợp các cột được xác định rõ. Truy vấn không thể có số cột thay đổi (trừ khi bạn đang sử dụng SQL động thông qua câu lệnh prepare).

+0

@Luv. . . Lời xin lỗi của tôi. Tôi không thấy liên kết SQLFiddle trong câu hỏi. Mã trên được kiểm tra và hoạt động. –

+0

Hoàn hảo nó hoạt động! Cảm ơn câu trả lời nhanh chóng và rất chính xác! Tôi sẽ chấp nhận nó như là một câu trả lời là một số khi giới hạn thời gian là hơn: p –

-2

ypu có thể sử dụng SQL động, nhưng bạn sẽ phải sử dụng thủ tục

1

Sử dụng truy vấn này để tìm ra số cột tiền tệ bạn sẽ cần:

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) 

Sau đó tự động tạo ra và thực hiện prepared statement để tạo kết quả, sử dụng giải pháp Gordon Linoff với kết quả truy vấn ở trên trong chuỗi này.

Các vấn đề liên quan