我的表来自存储过程的输出。看起来像:
col1
A
B
C
D
它可以少于或等于5行。
我希望它看起来像这样
Column1 Column2 Column3 Column4 column5
A B C D NULL
在MYSQL中有没有办法实现这一目标?
答案 0 :(得分:2)
在MySQL 8+中,使用ROW_NUMBER
和数据透视查询是一种相当简单的方法:
WITH cte AS (
SELECT col1, ROW_NUMBER() OVER (ORDER BY col1) rn
FROM yourTable
)
SELECT
MAX(CASE WHEN rn = 1 THEN col1 END) AS Column1,
MAX(CASE WHEN rn = 2 THEN col1 END) AS Column2,
MAX(CASE WHEN rn = 3 THEN col1 END) AS Column3,
MAX(CASE WHEN rn = 4 THEN col1 END) AS Column4,
MAX(CASE WHEN rn = 5 THEN col1 END) AS Column5
FROM cte;
答案 1 :(得分:2)
在MySQL 8.0以下,此方法变得更加复杂。
关于第一个查询的难点的简单解释
内的子查询
SELECT
GROUP_CONCAT(t.col1 ORDER BY col1 ASC) AS cvs
, COUNT(*) AS t_count
FROM
t
正在创建一个用逗号分隔的值列表。
然后,将SQL数字生成器与嵌套的SUBSTRING_INDEX()
函数结合使用,将逗号分隔的值拆分为记录。
然后GROUP_CONCAT()
将其合并为一个字符串,并最终转化为用户变量,基本上是在生成动态SQL时看起来像'<value>' AS Column<number>[, ...]
,SELECT @aggregateSQLPart;
会向您显示
查询
SET @aggregateSQLPart = NULL;
# set max of GROUP_CONCAT higher as it defaults to 1024 bytes.
SET SESSION group_concat_max_len = @@max_allowed_packet;
SELECT
DISTINCT
GROUP_CONCAT(CONCAT("'",
SUBSTRING_INDEX(
SUBSTRING_INDEX(
t.cvs
, ','
, number_generator.number
)
, ','
, -1
) , "'" , " AS Column", number_generator.number
))
INTO @aggregateSQLPart
FROM (
SELECT
@row := @row + 1 AS number
FROM (
SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row1
CROSS JOIN (
SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row2
CROSS JOIN (
SELECT @row := 0
) init_user_params
) AS number_generator
CROSS JOIN (
SELECT
GROUP_CONCAT(t.col1 ORDER BY col1 ASC) AS cvs
, COUNT(*) AS t_count
FROM
t
) AS t
WHERE
number BETWEEN 1 AND t_count;
SELECT @aggregateSQLPart;
SET @SQL = CONCAT("
SELECT
"
, @aggregateSQLPart
);
SELECT @SQL;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
结果
| Column1 | Column2 | Column3 | Column4 | Column5 |
| ------- | ------- | ------- | ------- | ------- |
| A | B | C | D | E |
请参阅demo
注意,不要怀疑它在“测试”服务器上平均运行大约5-10 ms的性能。也请注意,我选择了用户变量,因此您可以看到有什么不足之处在两者之间。