MySQL-如何将列解压到行?
我现在可能看不太清楚,但我在MySQL中有一个表,看起来像这样:MySQL-如何将列解压到行?,mysql,sql,union,unpivot,lateral-join,Mysql,Sql,Union,Unpivot,Lateral Join,我现在可能看不太清楚,但我在MySQL中有一个表,看起来像这样: ID | a | b | c 1 | a1 | b1 | c1 2 | a2 | b2 | c2 出于某种原因(实际上是另一个表上的联接-基于ID,但我认为如果有人能帮助我完成这部分,我可以自己完成其余部分),我需要这些行变成这样: 1 | a1 | a 1 | b1 | b 1 | c1 | c 2 | a2 | a 2 | b2 | b 2 | c2 | c 因此,基本上,我需要查看如下行:ID,columnti
ID | a | b | c
1 | a1 | b1 | c1
2 | a2 | b2 | c2
出于某种原因(实际上是另一个表上的联接-基于ID
,但我认为如果有人能帮助我完成这部分,我可以自己完成其余部分),我需要这些行变成这样:
1 | a1 | a
1 | b1 | b
1 | c1 | c
2 | a2 | a
2 | b2 | b
2 | c2 | c
因此,基本上,我需要查看如下行:ID
,columntitle
,value
有什么方法可以轻松做到这一点吗?尝试使用
您正在尝试取消填充数据。MySQL没有unpivot函数,因此必须使用UNION ALL
查询将列转换为行:
select id, 'a' col, a value
from yourtable
union all
select id, 'b' col, b value
from yourtable
union all
select id, 'c' col, c value
from yourtable
看
这也可以使用交叉连接来完成:
select t.id,
c.col,
case c.col
when 'a' then a
when 'b' then b
when 'c' then c
end as data
from yourtable t
cross join
(
select 'a' as col
union all select 'b'
union all select 'c'
) c
参见这花了很长时间,但MySQL版本8.0.14最终增加了对横向连接的支持——官方术语是 这是一个非常强大的功能,在多种情况下都很方便,包括取消表列到行的驱动 您可以按如下方式表达查询:
select t.id, x.*
from mytable t
cross join lateral (
select a, 'a'
union all select b, 'b'
union all select c, 'c'
) as x(col1, col2)
与典型的cannonical解决方案相比,这似乎没有太大的区别-毕竟,我们仍然在侧向衍生表中使用union all
。。。但是不要弄错了:这个查询只扫描表一次,而另一种方法需要对每一列进行一次扫描才能取消PIVOT。因此,这样做效率更高,而且随着表变大和/或需要取消插入更多列,性能增益会显著增加
一句话:如果您正在运行MySQL 8.0.14或更高版本,只需使用此技术。从那个版本开始,这是在MYSQL中取消PIVOT的标准方法
:
样本数据:
ID | a | b | c
-: | :- | :- | :-
1 | a1 | b1 | c1
2 | a2 | b2 | c2
你的意思是“ID,value,columntitle”?是的,但是顺序并不重要,只要行是ID-columntitle-values谢谢。所以看来根本没有一条真正的捷径(这是相当多的列,我认为对于每一列都有一种比“select…from…”更简单的方法。@user2128539查看我的编辑,我包括了一种不同的方法来解除数据的隐藏。@user2128539您应该接受解决问题的答案。救生员回答摆脱
WHERE
子句。否则,您只显示一列。)每个ID的umn,而不是每个ID的所有列。
ID | a | b | c
-: | :- | :- | :-
1 | a1 | b1 | c1
2 | a2 | b2 | c2
id | col1 | col2
-: | :--- | :---
1 | a1 | a
1 | b1 | b
1 | c1 | c
2 | a2 | a
2 | b2 | b
2 | c2 | c
select t.id, x.*
from mytable t
cross join lateral (values
row(a, 'a'),
row(b, 'b'),
row(c, 'c')
) as x(col1, col2);