Khi bạn đang cố gắng xoay giá trị động hoặc giá trị không xác định, tôi luôn khuyên bạn nên bắt đầu với phiên bản tĩnh hoặc mã hóa cứng của truy vấn trước, sau đó chuyển đổi nó thành SQL động.
MySQL không có hàm PIVOT nên bạn sẽ cần sử dụng hàm tổng hợp với biểu thức CASE để nhận kết quả. Phiên bản tĩnh của mã sẽ tương tự như sau:
select t.id teamid,
t.name teamname,
p.id processid,
p.name processname,
max(case when pd.keyname = 'shape' then tpd.value end) shape,
max(case when pd.keyname = 'vegetable' then tpd.value end) vegetable,
max(case when pd.keyname = 'fruit' then tpd.value end) fruit,
max(case when pd.keyname = 'animal' then tpd.value end) animal
from teams t
inner join teamprocesses tp
on t.id = tp.teamid
inner join TeamProcessDetails tpd
on tp.id = tpd.teamProcessId
inner join processes p
on tp.processid = p.id
inner join processdetails pd
on p.id = pd.processid
and tpd.processDetailsid = pd.id
group by t.id, t.name, p.id, p.name;
Xem SQL Fiddle with Demo .
Bây giờ nếu bạn sắp có một số keynames
không xác định mà bạn muốn chuyển đổi thành cột, thì bạn sẽ cần sử dụng tuyên bố đã chuẩn bị sẵn
để tạo SQL động. Mã sẽ tương tự như:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when pd.keyname = ''',
keyname,
''' then tpd.value end) AS ',
replace(keyname, ' ', '')
)
) INTO @sql
from ProcessDetails;
SET @sql
= CONCAT('SELECT t.id teamid,
t.name teamname,
p.id processid,
p.name processname, ', @sql, '
from teams t
inner join teamprocesses tp
on t.id = tp.teamid
inner join TeamProcessDetails tpd
on tp.id = tpd.teamProcessId
inner join processes p
on tp.processid = p.id
inner join processdetails pd
on p.id = pd.processid
and tpd.processDetailsid = pd.id
group by t.id, t.name, p.id, p.name;');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Xem SQL Fiddle with Demo .
Một điều cần ghi nhớ GROUP_CONCAT
hàm tạo chuỗi cột có độ dài tối đa mặc định là 1024, vì vậy nếu bạn có nhiều ký tự trong chuỗi này, bạn có thể phải thay đổi giá trị phiên cho group_concat_max_len
.
Truy vấn này sẽ cho kết quả:
| TEAMID | TEAMNAME | PROCESSID | PROCESSNAME | SHAPE | VEGETABLE | FRUIT | ANIMAL |
| 1 | teamA | 1 | processA | circle | carrot | apple | (null) |
| 1 | teamA | 2 | processB | (null) | (null) | (null) | dog |