首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对oracle中的多个列进行透视和排序

对oracle中的多个列进行透视和排序
EN

Stack Overflow用户
提问于 2021-05-22 06:44:59
回答 2查看 35关注 0票数 0

我知道如何在oracle中透视查询,但我需要按列对结果进行排序。

下表:

代码语言:javascript
运行
复制
Customer_id   Month   Sales_amt   Bill_amt
1             1       10          10
2             1       20          20
3             1       30          30
1             2       20          20
2             2       20          0
3             2       30          30

如果我做了轴心句

代码语言:javascript
运行
复制
SELECT * 
  FROM t
 PIVOT (
        SUM(sales_amt) AS sales, SUM(bill_amt) AS bill FOR month IN (1,2)
       );

结果是:

代码语言:javascript
运行
复制
Customer_id   1_sales 1_bill 2_sales 2_bill 
1             10      10     20      20       

但我需要先获取销售列,然后再获取账单列。

代码语言:javascript
运行
复制
Customer_id   1_sales 2_sales 1_bill 2_bill 
1             10      20      10      20       

我怎样才能得到这份订单呢?

编辑:我需要以一种动态的方式来做这件事,因为我将把它用于一个授权的报告

EN

回答 2

Stack Overflow用户

发布于 2021-05-22 09:19:56

简单-不要选择*,按需要的顺序选择显式列。

请注意,如果自动命名的列以数字开头,则需要在它们周围使用双引号(列名的其余部分将全部大写,而不是如何显示它们)。

如下所示:

代码语言:javascript
运行
复制
select customer_id, "1_SALES", "2_SALES", "1_BILL", "2_BILL" [ ... ]
from   ...
..........

在执行此操作时,还可以为列指定更标准的名称(这样它们就不会以数字开头,因此不需要用双引号括起来)。

票数 0
EN

Stack Overflow用户

发布于 2021-05-24 02:06:54

您可以将当前查询转换为包含条件聚合逻辑的查询,例如

代码语言:javascript
运行
复制
SELECT customer_id, 
       SUM(CASE WHEN month = 1 THEN sales_amt END) AS "1_SALES",
       SUM(CASE WHEN month = 2 THEN sales_amt END) AS "2_SALES",
       SUM(CASE WHEN month = 1 THEN bill_amt END) AS "1_BILL",
       SUM(CASE WHEN month = 2 THEN bill_amt END) AS "2_BILL"
  FROM t
 GROUP BY customer_id 

以便对这些列进行排序。

要使查询动态化,请使用以下创建存储函数的代码

代码语言:javascript
运行
复制
CREATE OR REPLACE FUNCTION Get_Pivoted_Sales RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols      VARCHAR2(32767);
BEGIN
  SELECT LISTAGG('SUM(CASE WHEN month='||month||' THEN '||column_name||' END) AS "'||cn||'"',',') 
          WITHIN GROUP ( ORDER BY column_name DESC, month )        
    INTO v_cols
    FROM ( SELECT DISTINCT month,column_name,month||'_'||RTRIM(column_name,'_AMT') AS cn
             FROM t
            CROSS JOIN ( SELECT column_name
                           FROM user_tab_cols 
                          WHERE table_name = 'T' 
                            AND column_name NOT IN ('CUSTOMER_ID','MONTH') ) ); 

  v_sql :='SELECT customer_id,'|| v_cols ||'
             FROM t
            GROUP BY customer_id';

  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;
/

其中假设表被创建为

代码语言:javascript
运行
复制
CREATE TABLE t
(
  customer_id INT,
  month       INT,
  sales_amt   NUMBER,
  bill_amt    NUMBER
)

然后从SQL开发人员控制台调用该函数,如下所示

代码语言:javascript
运行
复制
SQL> DECLARE
    res SYS_REFCURSOR;
BEGIN
   :res := Get_Pivoted_Sales;
END;
/

SQL> PRINT res;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67644570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档