Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:将单行显示为列(只需通过选择)_Mysql_Sql_Unpivot - Fatal编程技术网

MySQL:将单行显示为列(只需通过选择)

MySQL:将单行显示为列(只需通过选择),mysql,sql,unpivot,Mysql,Sql,Unpivot,有没有一种简单的方法可以选择MySQL中的一行并将其转置,以便列标题列在左侧列中,值列在右侧列中 例如: 与此相反: SELECT * FROM sock_table LIMIT 1; +---------+--------------+------------+ | sock_id | smell_factor | hole_count | +---------+--------------+------------+ | S000123 | 7.2 | 1

有没有一种简单的方法可以选择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是索引位置

这将适用于一个有几十个列标题的表,因此键入标题是一件非常麻烦的事情。

在MYSQL中,使用UNION ALL取消PIVOT:

(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)
重要提示:

这要求每列有一个子查询

没有订单的限制是不稳定的;您需要一个确定的ORDERBY子句——我假设可以使用列id对记录进行排序

值的数据类型需要一致——如果不是这样,您可能需要强制转换它们

编辑

事实上,MySQL 8.0.19或更高版本的最新版本可以使用row和LATENAL值来表示这一点,从而缩短了查询:

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)
在MYSQL中,使用UNION ALL取消PIVOT:

(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)
重要提示:

这要求每列有一个子查询

没有订单的限制是不稳定的;您需要一个确定的ORDERBY子句——我假设可以使用列id对记录进行排序

值的数据类型需要一致——如果不是这样,您可能需要强制转换它们

编辑

事实上,MySQL 8.0.19或更高版本的最新版本可以使用row和LATENAL值来表示这一点,从而缩短了查询:

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)
假设sock_表由这三列组成,sock_id作为表的主键,以便在orderby子句中使用。然后,考虑使用这个动态查询语句,以获得未枢转的结果:

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; 
在这种情况下,不需要单独指定每个列名。

假设sock_表由这三列组成,并且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; 

在这种情况下,不需要单独指定每个列名。

对每个列使用联合查询。没有内置的功能可以做到这一点。只是更新了我的问题,指出键入列名将无法达到此目的。也许@Barmar是对的,因为缺少本机功能。如果您不想为每个列键入所有子查询,您可以创建一个存储过程,从INFORMATION_SCHEMA.COLUMNS表生成动态SQL。对每一列使用联合查询。没有内置的方法可以做到这一点。只是更新了我的问题,指出键入列名将无法达到此目的。也许@Barmar是对的,因为缺少本机功能。如果您不想为每个列键入所有子查询,您可以创建一个存储过程,从INFORMATION_SCHEMA.COLUMNS表生成动态SQL。感谢发布GMB,但我问题中的示例表过于简化,它将有更多的栏。@elPastor:所以你需要更多的联合所有成员,每个栏一个。Eeesh,好的。听起来这果汁不值得挤。无论如何,再次感谢。@elPastor:如果您运行的是MySQL 8.0.14或更高版本,请参阅我的编辑以获得替代方案。谢谢,但再次感谢,我必须键入几十列,我正在寻找一个简单的函数,我猜它不存在。感谢发布GMB,但我问题中的示例表过于简单,它将有更多的栏。@elPastor:所以你需要更多的联合所有成员,每个栏一个。Eeesh,好的。听起来这果汁不值得挤。无论如何,再次感谢。@elPastor:如果您运行的是MySQL 8.0.14或更高版本,请参阅我的编辑以获得替代方案。谢谢,但再次感谢,我必须键入几十列,我正在寻找一个简单的函数,我猜它不存在。