如何在 SQL 中转置查询结果?
Posted
技术标签:
【中文标题】如何在 SQL 中转置查询结果?【英文标题】:How can I transpose a query result in SQL? 【发布时间】:2019-07-03 18:44:00 【问题描述】:由于许多子查询,我有下表:
+---------------------------------------------+
| register | simulation | hasLimit | approved |
+---------------------------------------------+
| X | Y | Z | W |
+---------------------------------------------+
但我希望它是这样的:
+----------------+
| register | X |
+----------------+
| simulation | Y |
+----------------+
| hasLimit | Z |
+----------------+
| approved | W |
+----------------+
在 R 中,我会简单地使用函数 t() 进行转置,但在 SQL 中似乎有点困难。我试图理解在这种情况下应用的函数 pivot ,但这似乎有点奇怪,因为我实际上只是在转置,而不是旋转任何东西。
【问题讨论】:
用您正在使用的 DBMS(SQL Server、Oracle、mysql 等)标记您的问题 Google 中的“Columns to Rows SQL”应该这样做。 之前已经在这里回答过:***.com/questions/18026236/sql-server-columns-to-rows 【参考方案1】:您似乎想要一个“反透视”操作。
假设列的类型都兼容,可以使用union all
:
select 'register' as which, register as value union all
select 'simulation', simulation union all
select 'hasLimit', hasLimit union all
select 'approved', approved;
有些数据库要求每个子查询都有一个FROM
子句,例如from dual
。
这是非常少量的数据。对于较大的数据,我更喜欢横向连接,但语法(及其可用性)取决于数据库。
【讨论】:
我一开始展示的表本身并不是一个表,它是许多并排查询的结果,我将所有查询放在一个查询中,每个单独的查询都给了我某个数字(X、Y、Z、W)。我想我必须使用 unpivot 函数,但在生成此结果的查询中找不到如何执行此操作 @EduardaOliveira 为了能够使用 unpivoting,我们需要确保您的 DBMS 产品适合它。即你需要先告诉你的 DBMS。【参考方案2】:鉴于来自
的回报 SELECT 'x' AS register
, 'y' AS simulation
, 'z' AS hasLimit
, 'w' AS approved
我们可以将其包装在一组括号中,并在外部查询中将其作为内联视图引用。
例如:
SELECT CASE i.n
WHEN 1 THEN 'register'
WHEN 2 THEN 'simulation'
WHEN 3 THEN 'hasLimit'
WHEN 4 THEN 'approved'
END AS col1
, CASE i.n
WHEN 1 THEN q.register
WHEN 2 THEN q.simulation
WHEN 3 THEN q.hasLimit
WHEN 4 THEN q.approved
END AS col2
FROM (
SELECT 'x' AS register
, 'y' AS simulation
, 'z' AS hasLimit
, 'w' AS approved
) q
CROSS
JOIN ( SELECT 1 AS n
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
) i
ORDER
BY i.n
这似乎有点复杂,因为您已经有返回标量值的子查询,我们可以将它们与 UNION ALL
集合运算符结合起来
SELECT 'register' AS col1, ( scalar_subquery_for_x ) AS col2
UNION ALL
SELECT 'simulation' , ( scalar_subquery_for_y )
UNION ALL
SELECT 'hasLimit' , ( scalar_subquery_for_z )
UNION ALL
SELECT 'approved' , ( scalar_subquery_for_w )
如果我们需要有保证的顺序,我们可以将整个内容包裹在括号中并添加 ORDER BY 子句。 (如果没有 ORDER BY,我们确实观察到行是从 UNION ALL
“按顺序”返回的,但不能保证这种行为。)
【讨论】:
【参考方案3】:如下使用简单的UNPIVOT
,
SELECT Col, Val
FROM <Your Table>
UNPIVOT (Val FOR Col IN([register],[simulation],[hasLimit],[approved])) unpiv
【讨论】:
以上是关于如何在 SQL 中转置查询结果?的主要内容,如果未能解决你的问题,请参考以下文章