如何将这些 MySQL 结果转换(或可能是枢轴)到一个综合视图中?
How to transform (or possibly pivot) these MySQL results into a consolidated view?
MySQL 查询的结果如下所示:
key | name | value
----+------+--------
1 | foo | alpha
1 | bar | beta
2 | foo | charlie
2 | bar | delta
3 | foo | echo
如何将结果转换成这个?
key | foo | bar
----+---------+--------
1 | alpha | beta
2 | charlie | delta
3 | echo |
我更喜欢 SQL 解决方案,但结果被传递到 PHP 因此如果没有 SQL 解决方案,我可以使用 PHP 操作结果.我不愿意使用 PHP 但是因为我有一种感觉,对于 key
列中可能有上千个或更多不同值的查询,它会非常慢。
当我在 Google 上搜索答案时,我听说过使用术语 pivoting。我不完全理解这意味着什么,所以我不确定旋转是否与这里相关。
提前感谢您的任何建议。
只使用条件聚合:
select `key`,
max(case when name = 'foo' then value end) as foo,
max(case when name = 'bar' then value end) as bar
from t
group by `key`;
如果每个 key
有多个值,那么 group_concat()
可能比 max()
更合适。
如果您不知道可能的名称列表,请查看 Google "MySQL dynamic pivot" 示例以了解如何操作。这需要使用动态 SQL.
虽然 Gordon Linoff 的解决方案是公认的答案,但我还是决定添加一个示例来说明我是如何实现它的。这应该对以后遇到这个问题的人有所帮助!
-- create a table
CREATE TABLE `items` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`uuid` INT NOT NULL,
`key` VARCHAR(255) NOT NULL,
`value` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
-- insert some rows
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('1', '1', 'name', 'Foo');
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('2', '1', 'price', '100');
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('3', '2', 'name', 'Bar');
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('4', '2', 'price', '200');
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('5', '3', 'name', 'Baz');
-- and fetch them
SELECT `uuid`,
MAX(IF((`key` = 'name'), `value`, NULL)) AS `name`,
MAX(IF((`key` = 'price'), `value`, NULL)) AS `price`
FROM `items`
GROUP BY `uuid`;
MySQL 查询的结果如下所示:
key | name | value
----+------+--------
1 | foo | alpha
1 | bar | beta
2 | foo | charlie
2 | bar | delta
3 | foo | echo
如何将结果转换成这个?
key | foo | bar
----+---------+--------
1 | alpha | beta
2 | charlie | delta
3 | echo |
我更喜欢 SQL 解决方案,但结果被传递到 PHP 因此如果没有 SQL 解决方案,我可以使用 PHP 操作结果.我不愿意使用 PHP 但是因为我有一种感觉,对于 key
列中可能有上千个或更多不同值的查询,它会非常慢。
当我在 Google 上搜索答案时,我听说过使用术语 pivoting。我不完全理解这意味着什么,所以我不确定旋转是否与这里相关。
提前感谢您的任何建议。
只使用条件聚合:
select `key`,
max(case when name = 'foo' then value end) as foo,
max(case when name = 'bar' then value end) as bar
from t
group by `key`;
如果每个 key
有多个值,那么 group_concat()
可能比 max()
更合适。
如果您不知道可能的名称列表,请查看 Google "MySQL dynamic pivot" 示例以了解如何操作。这需要使用动态 SQL.
虽然 Gordon Linoff 的解决方案是公认的答案,但我还是决定添加一个示例来说明我是如何实现它的。这应该对以后遇到这个问题的人有所帮助!
-- create a table
CREATE TABLE `items` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`uuid` INT NOT NULL,
`key` VARCHAR(255) NOT NULL,
`value` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
-- insert some rows
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('1', '1', 'name', 'Foo');
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('2', '1', 'price', '100');
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('3', '2', 'name', 'Bar');
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('4', '2', 'price', '200');
INSERT INTO `items` (`id`, `uuid`, `key`, `value`) VALUES ('5', '3', 'name', 'Baz');
-- and fetch them
SELECT `uuid`,
MAX(IF((`key` = 'name'), `value`, NULL)) AS `name`,
MAX(IF((`key` = 'price'), `value`, NULL)) AS `price`
FROM `items`
GROUP BY `uuid`;