Oracle 中表的“转置”

Posted

技术标签:

【中文标题】Oracle 中表的“转置”【英文标题】:"Transpose" of a table in Oracle 【发布时间】:2016-03-12 00:59:43 【问题描述】:

我在弄清楚如何重新排列表格时遇到了很多麻烦。我有一张看起来像这样的大桌子:

+--------+-----------+
|  NAME  | ACCOUNT # |
+--------+-----------+
| Nike   |        87 |
| Nike   |        12 |
| Adidas |        80 |
| Adidas |        21 |
+--------+-----------+

我想把它重新排列成这样:

+------+--------+
| Nike | Adidas |
+------+--------+
|   87 |     80 |
|   12 |     21 |
+------+--------+

但我似乎无法弄清楚如何。我尝试使用 PIVOT,但这仅适用于聚合函数。我也尝试使用 FOR LOOP,但无法使其正常工作。

【问题讨论】:

告诉我们您尝试了什么以及为什么它不能满足您的需求。这表明您已经花时间尝试帮助自己,它使我们免于重复明显的答案,最重要的是它可以帮助您获得更具体和相关的答案!另见how to ask 向我们展示一些 SQL。如果您不需要聚合使用 MIN 或 MAX 函数 【参考方案1】:

您可以通过多种方式做到这一点,但都是通过枚举行来实现的。下面是一个使用条件聚合的例子:

select max(case when name = 'Nike' then account end) as Nike,
       max(case when name = 'Adidas' then account end) as Adidas
from (select t.*,
             row_number() over (partition by name order by account desc) as seqnum
      from t
     ) t
group by seqnum;

【讨论】:

感谢您的回答,但不幸的是,这对我不起作用——我应该提到的,但是有大约 200 个名字,所以我无法真正为每个名字写出条件语句。 @TinaBelcher 。 . .你可以。您可能会发现电子表格有助于生成代码。【参考方案2】:

再次考虑枢轴解决方案,但首先添加行号以滚动Name 组计数。下面假设一个自动编号 ID 字段:

SELECT * FROM
(
  SELECT Name, "Account #", 
         (ROW_NUMBER() OVER(PARTITION BY Name ORDER BY ID)) GrpRowNum
         /* ALT: (SELECT Count(*) FROM Table1 sub 
          *       WHERE sub.Name = Table1.Name AND sub.ID <= Table1.ID) GrpRowNum */             
  FROM Table1
)
PIVOT
(
  SUM("Account #")
  FOR Name IN ('Nike', 'Adidas')
)
ORDER BY RowNum;

但是,对于大约 200 个项目,如果没有各种解决方法(包括 PIVOT XML 输出或使用 PL/SQL 的存储过程),您将无法轻松呈现 Pivot 的 IN 子句。同样,您可以使用通用编码(Java、php、Python、R)来检索向量/数组中的SELECT DISTINCT Name FROM Table1 结果集,使用引号和逗号分隔符连接元素值(折叠或内爆数组),并将整个列表放在 @ 987654327@子句。

【讨论】:

以上是关于Oracle 中表的“转置”的主要内容,如果未能解决你的问题,请参考以下文章

转置 Oracle 表/数据集

Oracle:将列转置为行

转置列 Oracle sql

Oracle使用SQL实现矩阵转置

Oracle中的转置功能[重复]

转置和聚合 Oracle 列数据