MySQL 数据透视列
MySQL pivot column
我希望根据 MySQL 中的用户 ID 将单列数据转换为多行 - 我更愿意使用 sql 查询而不是外部工具来执行此操作。
我的具体情况似乎很简单,但我无法根据我发现的各种支点question/answer/examples弄清楚。
这是我目前的table:
╔════════╦═════════╦═════════╗
║ userID ║ object ║ index ║
╠════════╬═════════╣═════════╣
║ user1 ║ Apple ║ 1 ║
║ user1 ║ Orange ║ 2 ║
║ user1 ║ Pear ║ 3 ║
║ user2 ║ Kiwi ║ 1 ║
║ user2 ║ Melon ║ 2 ║
║ user2 ║ Mango ║ 3 ║
║ user3 ║ Apple ║ 1 ║
║ user3 ║ Melon ║ 2 ║
║ user3 ║ Pear ║ 3 ║
║ user3 ║ Mango ║ 4 ║
╚════════╩═════════╩═════════╝
这是期望的输出:
╔════════╦═════════╦═════════╦═════════╦═════════╗
║ userID ║ 1 ║ 2 ║ 3 ║ 4 ║
╠════════╬═════════╬═════════╬═════════╬═════════╣
║ user1 ║ Apple ║ Orange ║ Pear ║ empty ║
║ user2 ║ Kiwi ║ Melon ║ Mango ║ empty ║
║ user3 ║ Apple ║ Melon ║ Pear ║ Mango ║
╚════════╩═════════╩═════════╩═════════╩═════════╝
注意几点:
- userID 之后的列应该是给定对象的索引
用户
- 对象将以相同的顺序出现(我想这就是单个 column/row 枢轴的作用)
- 每个用户 ID 的对象数是可变的 - 列数应与任何单个用户的最大对象数相匹配。在上面的示例中,user3 有 4 个对象,因此我们在 userID 列之后有 4 列,即使其他用户的对象较少。当用户没有该列的数据时,我很乐意留下空白条目。
我敢肯定这实际上很简单,我想多了。
编辑:我根据 Gordon Linoff 的评论对 table 进行了轻微编辑,以包含我作为初始 [=45= 的一部分的排序索引].
另外,根据 Gordon 的回答,同一问题的替代版本。
如果我预先知道我应该拥有的最大列数(在此示例中,对象为 4),这会简化事情吗?例如在 运行 我的查询之前,我可以用 5 列创建 table。
你不能随心所欲地做你想做的事,原因有两个:
- SQL 表表示无序集,因此除非列指定顺序,否则没有顺序。
- SQL 语句中的列是固定的。
可能足够接近的是将所有值放在一列中:
select userId, group_concat(object)
from table t
group by userId;
您可以将 group_concat()
修改为 separator
和 order by
以指定分隔符(默认逗号)或特定顺序。
如果你真的想要可变数量的列,那么你将不得不使用动态 SQL -- prepare
和 exec
.
我希望根据 MySQL 中的用户 ID 将单列数据转换为多行 - 我更愿意使用 sql 查询而不是外部工具来执行此操作。
我的具体情况似乎很简单,但我无法根据我发现的各种支点question/answer/examples弄清楚。
这是我目前的table:
╔════════╦═════════╦═════════╗
║ userID ║ object ║ index ║
╠════════╬═════════╣═════════╣
║ user1 ║ Apple ║ 1 ║
║ user1 ║ Orange ║ 2 ║
║ user1 ║ Pear ║ 3 ║
║ user2 ║ Kiwi ║ 1 ║
║ user2 ║ Melon ║ 2 ║
║ user2 ║ Mango ║ 3 ║
║ user3 ║ Apple ║ 1 ║
║ user3 ║ Melon ║ 2 ║
║ user3 ║ Pear ║ 3 ║
║ user3 ║ Mango ║ 4 ║
╚════════╩═════════╩═════════╝
这是期望的输出:
╔════════╦═════════╦═════════╦═════════╦═════════╗
║ userID ║ 1 ║ 2 ║ 3 ║ 4 ║
╠════════╬═════════╬═════════╬═════════╬═════════╣
║ user1 ║ Apple ║ Orange ║ Pear ║ empty ║
║ user2 ║ Kiwi ║ Melon ║ Mango ║ empty ║
║ user3 ║ Apple ║ Melon ║ Pear ║ Mango ║
╚════════╩═════════╩═════════╩═════════╩═════════╝
注意几点:
- userID 之后的列应该是给定对象的索引 用户
- 对象将以相同的顺序出现(我想这就是单个 column/row 枢轴的作用)
- 每个用户 ID 的对象数是可变的 - 列数应与任何单个用户的最大对象数相匹配。在上面的示例中,user3 有 4 个对象,因此我们在 userID 列之后有 4 列,即使其他用户的对象较少。当用户没有该列的数据时,我很乐意留下空白条目。
我敢肯定这实际上很简单,我想多了。
编辑:我根据 Gordon Linoff 的评论对 table 进行了轻微编辑,以包含我作为初始 [=45= 的一部分的排序索引].
另外,根据 Gordon 的回答,同一问题的替代版本。
如果我预先知道我应该拥有的最大列数(在此示例中,对象为 4),这会简化事情吗?例如在 运行 我的查询之前,我可以用 5 列创建 table。
你不能随心所欲地做你想做的事,原因有两个:
- SQL 表表示无序集,因此除非列指定顺序,否则没有顺序。
- SQL 语句中的列是固定的。
可能足够接近的是将所有值放在一列中:
select userId, group_concat(object)
from table t
group by userId;
您可以将 group_concat()
修改为 separator
和 order by
以指定分隔符(默认逗号)或特定顺序。
如果你真的想要可变数量的列,那么你将不得不使用动态 SQL -- prepare
和 exec
.