将行转换为列的动态 SQL 代码
Dynamic SQL code to convert rows to columns
我在 MySQL 中有一个 table 是这样的:
+-------+----------+
| am | ipiresia |
+-------+----------+
| 50470 | 29 |
| 50470 | 43 |
| 50433 | 29 |
| 6417 | 51 |
| 6417 | 52 |
| 6417 | 53 |
| 4960 | 25 |
| 4960 | 26 |
| 5567 | 89 |
| 6716 | 88 |
+-------+----------+
我想这样改造:
+-------+-----------+-----------+-----------+
| am | ipiresia1 | ipiresia2 | ipiresia3 |
+-------+-----------+-----------+-----------+
| 50470 | 29 | 43 | |
| 50433 | 29 | | |
| 6417 | 51 | 52 | 53 |
| 4960 | 25 | 26 | |
| 5567 | 89 | | |
| 6716 | 88 | | |
+-------+-----------+-----------+-----------+
当然这只是table的一部分。每个 'am' 的 'ipiresia' 最多出现 5 次,所以我认为动态枢轴 table 可以完成这项工作,但我不知道该怎么做。
就像 Orangepill 所建议的那样,group concat 是这里的答案,但是你会在一栏中得到 ipiresia 结果:
SELECT am, GROUP_CONCAT(ipiresia)
FROM table
GROUP BY am
你应该有类似
+-------+-----------+
| am | ipiresia |
+-------+-----------+
| 50470 | 29, 43 |
| 50433 | 29 |
| 6417 | 51, 52, 53|
| 4960 | 25, 26 |
| 5567 | 89 |
| 6716 | 88 |
+-------+-----------+
首先 - 再添加一个具有确切 ipiresia
数字的列 -
+-------+----------+-----+
| am | ipiresia | num |
+-------+----------+-----+
| 50470 | 29 | 1 |
| 50470 | 43 | 2 |
| 50433 | 29 | 1 |
| 6417 | 51 | 1 |
| 6417 | 52 | 2 |
| 6417 | 53 | 3 |
| 4960 | 25 | 1 |
| 4960 | 26 | 2 |
| 5567 | 89 | 1 |
| 6716 | 88 | 1 |
+-------+----------+-----+
然后使用动态枢轴 -
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(num = ''',
num,
''', ipiresia, NULL)) AS ',
CONCAT('ipiresia', num)
)
) INTO @sql
FROM ipiresia;
SET @sql = CONCAT('SELECT am, ', @sql, ' FROM ipiresia GROUP BY am');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
结果-
+-------+-----------+-----------+-----------+
| am | ipiresia1 | ipiresia2 | ipiresia3 |
+-------+-----------+-----------+-----------+
| 4960 | 25 | 26 | NULL |
| 5567 | 89 | NULL | NULL |
| 6417 | 51 | 52 | 53 |
| 6716 | 88 | NULL | NULL |
| 50433 | 29 | NULL | NULL |
| 50470 | 29 | 43 | NULL |
+-------+-----------+-----------+-----------+
我在 MySQL 中有一个 table 是这样的:
+-------+----------+
| am | ipiresia |
+-------+----------+
| 50470 | 29 |
| 50470 | 43 |
| 50433 | 29 |
| 6417 | 51 |
| 6417 | 52 |
| 6417 | 53 |
| 4960 | 25 |
| 4960 | 26 |
| 5567 | 89 |
| 6716 | 88 |
+-------+----------+
我想这样改造:
+-------+-----------+-----------+-----------+
| am | ipiresia1 | ipiresia2 | ipiresia3 |
+-------+-----------+-----------+-----------+
| 50470 | 29 | 43 | |
| 50433 | 29 | | |
| 6417 | 51 | 52 | 53 |
| 4960 | 25 | 26 | |
| 5567 | 89 | | |
| 6716 | 88 | | |
+-------+-----------+-----------+-----------+
当然这只是table的一部分。每个 'am' 的 'ipiresia' 最多出现 5 次,所以我认为动态枢轴 table 可以完成这项工作,但我不知道该怎么做。
就像 Orangepill 所建议的那样,group concat 是这里的答案,但是你会在一栏中得到 ipiresia 结果:
SELECT am, GROUP_CONCAT(ipiresia)
FROM table
GROUP BY am
你应该有类似
+-------+-----------+
| am | ipiresia |
+-------+-----------+
| 50470 | 29, 43 |
| 50433 | 29 |
| 6417 | 51, 52, 53|
| 4960 | 25, 26 |
| 5567 | 89 |
| 6716 | 88 |
+-------+-----------+
首先 - 再添加一个具有确切 ipiresia
数字的列 -
+-------+----------+-----+
| am | ipiresia | num |
+-------+----------+-----+
| 50470 | 29 | 1 |
| 50470 | 43 | 2 |
| 50433 | 29 | 1 |
| 6417 | 51 | 1 |
| 6417 | 52 | 2 |
| 6417 | 53 | 3 |
| 4960 | 25 | 1 |
| 4960 | 26 | 2 |
| 5567 | 89 | 1 |
| 6716 | 88 | 1 |
+-------+----------+-----+
然后使用动态枢轴 -
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(num = ''',
num,
''', ipiresia, NULL)) AS ',
CONCAT('ipiresia', num)
)
) INTO @sql
FROM ipiresia;
SET @sql = CONCAT('SELECT am, ', @sql, ' FROM ipiresia GROUP BY am');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
结果-
+-------+-----------+-----------+-----------+
| am | ipiresia1 | ipiresia2 | ipiresia3 |
+-------+-----------+-----------+-----------+
| 4960 | 25 | 26 | NULL |
| 5567 | 89 | NULL | NULL |
| 6417 | 51 | 52 | 53 |
| 6716 | 88 | NULL | NULL |
| 50433 | 29 | NULL | NULL |
| 50470 | 29 | 43 | NULL |
+-------+-----------+-----------+-----------+