我在这里阅读了这个答案,MySQL - Rows to Columns,并且我已经能够将其应用于我的情况,直到聚合函数(步骤3)。
我正在尝试将下表itemname中的行转换为列:itemvalue
| 主机ID | 项目名 | 项目值 |
|---|---|---|
| 1 | 地址 | 12街 |
| 2 | 电子邮件 | 所以@gmail |
| 3 | 姓名 | 传奇 |
我应用了以下代码:
create view table_extended as (
select
history.*,
case when itemname = "address" then itemvalue end as address,
case when itemname = "email" then itemvalue end as email,
case when itemname = "name" then itemvalue end as name
from history
);
Run Code Online (Sandbox Code Playgroud)
现在我有了table_extended:
| 主机ID | 项目名 | 项目值 | 地址 | 电子邮件 | 姓名 |
|---|---|---|---|---|---|
| 1 | 地址 | 12街 | 12街 | 无效的 | 无效的 |
| 1 | 电子邮件 | 所以@gmail | 无效的 | 所以@gmail | 无效的 |
| 1 | 姓名 | 传奇 | 无效的 | 无效的 | 传奇 |
在步骤 3中,他使用sum聚合扩展表,其中所有值都是整数。我尝试使用以下代码创建另一个视图,但当然这些是字符串,因此它将除 hostid 之外的所有行都变为 0。
create view history_itemvalue_pivot as (
select
hostid,
sum(address) as address,
sum(email) as email,
sum(name) as name
from history_extended
group by hostid
);
Run Code Online (Sandbox Code Playgroud)
它看起来像这样:
| 主机ID | 地址 | 电子邮件 | 姓名 |
|---|---|---|---|
| 1 | 0 | 0 | 0 |
如何合并所有行NULL以获得以下内容:
| 主机ID | 地址 | 电子邮件 | 姓名 |
|---|---|---|---|
| 1 | 12街 | 所以@gmail | 传奇 |
您可以使用GROUP_CONCAT字符串函数。该函数尝试连接子句中匹配的字符串GROUP BY,当遇到一个NULL值时,它会忽略它。
SELECT hostid,
GROUP_CONCAT(address) AS address,
GROUP_CONCAT(email) AS email,
GROUP_CONCAT(name) AS name
FROM (SELECT history.*,
CASE WHEN itemname = "address" THEN itemvalue END AS address,
CASE WHEN itemname = "email" THEN itemvalue END AS email,
CASE WHEN itemname = "name" THEN itemvalue END AS name
FROM history
) history_extended
GROUP BY hostid
Run Code Online (Sandbox Code Playgroud)
在这里查看演示。
注意:我注意到,在您对该表的第一次引用中,您有三个不同的主机 ID,而在接下来的引用中,您仅引用了一个主机 ID。有一些错别字吗?