MySQL:将单行显示为列(简单地说,通过 SELECT)
Posted
技术标签:
【中文标题】MySQL:将单行显示为列(简单地说,通过 SELECT)【英文标题】:MySQL: Display single row as column (simply, via SELECT) 【发布时间】:2020-10-05 19:54:23 【问题描述】:是否有一种简单的方法可以在 mysql 中选择单行并将其转置,以便列标题列在左侧列中,值列在右侧列中?
例子:
而不是这个:
SELECT * FROM sock_table LIMIT 1;
+---------+--------------+------------+
| sock_id | smell_factor | hole_count |
+---------+--------------+------------+
| S000123 | 7.2 | 1 |
+---------+--------------+------------+
...你可以这样做:
SELECT TRANSPOSE(*) FROM sock_table LIMIT 1;
sock_id S000123
smell_factor 7.2
hole_count 1
对于熟悉python-pandas的朋友,df.loc[0]
(其中0是索引位置)会自动执行这个功能。
这适用于具有数十个列标题的表格,因此输入标题比它的价值更麻烦。
【问题讨论】:
对每列使用UNION
的查询。
没有任何内置功能可以做到这一点。
刚刚更新了我的问题,指出输入列名会破坏目的。也许@Barmar 是对的:缺乏原生功能。
如果您不想为每列键入所有子查询,您可以创建一个存储过程,从INFORMATION_SCHEMA.COLUMNS
表中生成动态 SQL。
【参考方案1】:
在 MYSQL 中,使用UNION ALL
进行反透视:
(select 'stock_id' col, stock_id val FROM stock_table order by id limit 1)
union all (select 'smell_factor' col, smell_factor val FROM stock_table order by id limit 1)
union all (select 'hole_count' col, hole_count val FROM stock_table order by id limit 1)
重要提示:
这需要每列一个子查询
LIMIT
没有ORDER BY
是不稳定的;您需要一个确定性的 ORDER BY
子句 - 我假设列 id
可用于对记录进行排序
值的数据类型需要保持一致 - 如果不是这种情况,您可能需要 cast
它们
编辑
实际上,最新版本的 MySQL(8.0.19 或更高版本)可以使用 values row()
和 lateral
来表达这一点,从而缩短查询:
select x.*
from (select * from mytable order by id limit 1) t,
lateral (values
row ('stock_id', t.stock_id),
row ('smell_factor', t.smell_factor),
row ('hole_count', t.hole_count)
) x(col, val)
【讨论】:
感谢您发布 GMB,但我的问题中的示例表过于简单,它将包含更多列。 @elPastor:所以您需要更多union all
成员(每列一个)。
哎呀,好的。听起来果汁不值得挤。无论如何,再次感谢。
@elPastor:如果您运行的是 MySQL 8.0.14 或更高版本,请参阅我的编辑以获取替代方案。
谢谢,但同样,我必须输入几十列,我正在寻找一个简单的函数,我猜它不存在。【参考方案2】:
假设sock_table
由这三列组成,sock_id
作为表的主键,以便在ORDER BY
子句中使用。然后,考虑使用此动态查询语句以获得非透视结果:
SET @sql = NULL;
SELECT GROUP_CONCAT(
CONCAT(
'( SELECT "',column_name,'" AS col_name, ',column_name,' AS value
FROM ',table_name,' ORDER BY sock_id LIMIT 1 ) ' )
SEPARATOR 'UNION ALL ')
INTO @sql
FROM information_schema.columns c
WHERE table_name = 'sock_table'
ORDER BY ordinal_position;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Demo
这种情况下,不需要单独指定每个列名。
【讨论】:
以上是关于MySQL:将单行显示为列(简单地说,通过 SELECT)的主要内容,如果未能解决你的问题,请参考以下文章