如何将 SQL 中的行转换为列?
How to convert row into columns in SQL?
给定一个由一行组成的 table,我想将其转置为一个由一列组成的 table。所以基本上,它是 this 问题中所问内容的逆运算。我正在使用 MEMSQL,但欢迎任何类似 SQL 的方法。
所以如果我的 table 看起来像:
---------------------------------------------------------------------
| FirstName |Amount| PostalCode | LastName | AccountNumber |
---------------------------------------------------------------------
| John | 2.4 | ZH1E4A | Fork | 857685 |
---------------------------------------------------------------------
我希望获得以下输出:
--------------
| anyName |
--------------
| John |
| 2.4 |
| JZH1E4Aohn |
| Fork |
| 857685 |
--------------
编辑:我知道这可以使用 union all
来完成,但是如果行很长,使用 union all
可能会花费很多时间。我正在寻找最有效的方法。
您可以使用union all
,您可能需要将整数值转换为字符串。
select firstName as anyName from yourTable
union all
select Amount from yourTable
union all
select PostalCode from yourTable
union all
select LastName from yourTable
union all
select AccountNumber from yourTable
您想对数据进行逆透视。挑战在于处理数据类型。您需要将它们全部转换为相同的类型。据推测,这仅适用于 amount
并且可能适用于 accountnumber
:
select firstName as anyName from t
union all
select cast(Amount as char) from t
union all
select PostalCode from t
union all
select LastName from t
union all
select cast(AccountNumber as char) from t;
如果您的 table 非常大或者确实是一个复杂的视图,那么还有其他方法不需要为每一列扫描一次 table。
您还可以使用 cross join
和 case
:
select (case when n.n = 1 then firstName
when n.n = 2 then cast(Amount as char)
when n.n = 3 then PostalCode
when n.n = 4 then lastName
when n.n = 5 then cast(AccountNumber as char)
end) as anyName
from t cross join
(select 1 as n union all select 2 union all select 3 union all select 4 union all select 5
) n
根据我在 memSQL 方面的经验,我建议编写一个转换脚本以一次插入目标 table 每一列(查询信息模式,然后迭代它,将插入推入每次迭代的目标)。 MemSQL 似乎对复杂的 SQL 有问题...尤其是在开发过程中弄清楚事情时 运行 的 adhoc 风格会询问您,例如您正在做的事情.. . 当然,他们的营销人员会告诉你其他情况,当他们从 investors/customers 中提取现金时,功能将被添加,所以也许在一两年内它不会厌倦堆叠联合,但我建议避免它们超过如果它不是简单的 select 联合,绝对要避免。
给定一个由一行组成的 table,我想将其转置为一个由一列组成的 table。所以基本上,它是 this 问题中所问内容的逆运算。我正在使用 MEMSQL,但欢迎任何类似 SQL 的方法。
所以如果我的 table 看起来像:
---------------------------------------------------------------------
| FirstName |Amount| PostalCode | LastName | AccountNumber |
---------------------------------------------------------------------
| John | 2.4 | ZH1E4A | Fork | 857685 |
---------------------------------------------------------------------
我希望获得以下输出:
--------------
| anyName |
--------------
| John |
| 2.4 |
| JZH1E4Aohn |
| Fork |
| 857685 |
--------------
编辑:我知道这可以使用 union all
来完成,但是如果行很长,使用 union all
可能会花费很多时间。我正在寻找最有效的方法。
您可以使用union all
,您可能需要将整数值转换为字符串。
select firstName as anyName from yourTable
union all
select Amount from yourTable
union all
select PostalCode from yourTable
union all
select LastName from yourTable
union all
select AccountNumber from yourTable
您想对数据进行逆透视。挑战在于处理数据类型。您需要将它们全部转换为相同的类型。据推测,这仅适用于 amount
并且可能适用于 accountnumber
:
select firstName as anyName from t
union all
select cast(Amount as char) from t
union all
select PostalCode from t
union all
select LastName from t
union all
select cast(AccountNumber as char) from t;
如果您的 table 非常大或者确实是一个复杂的视图,那么还有其他方法不需要为每一列扫描一次 table。
您还可以使用 cross join
和 case
:
select (case when n.n = 1 then firstName
when n.n = 2 then cast(Amount as char)
when n.n = 3 then PostalCode
when n.n = 4 then lastName
when n.n = 5 then cast(AccountNumber as char)
end) as anyName
from t cross join
(select 1 as n union all select 2 union all select 3 union all select 4 union all select 5
) n
根据我在 memSQL 方面的经验,我建议编写一个转换脚本以一次插入目标 table 每一列(查询信息模式,然后迭代它,将插入推入每次迭代的目标)。 MemSQL 似乎对复杂的 SQL 有问题...尤其是在开发过程中弄清楚事情时 运行 的 adhoc 风格会询问您,例如您正在做的事情.. . 当然,他们的营销人员会告诉你其他情况,当他们从 investors/customers 中提取现金时,功能将被添加,所以也许在一两年内它不会厌倦堆叠联合,但我建议避免它们超过如果它不是简单的 select 联合,绝对要避免。