Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在oracle中透视和排序多个列_Sql_Oracle_Pivot - Fatal编程技术网

Sql 在oracle中透视和排序多个列

Sql 在oracle中透视和排序多个列,sql,oracle,pivot,Sql,Oracle,Pivot,我知道如何在oracle中透视查询,但我需要按列对结果进行排序 这是表格: 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

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

这是表格:

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
如果我做重点句子

SELECT * 
  FROM t
 PIVOT (
        SUM(sales_amt) AS sales, SUM(bill_amt) AS bill FOR month IN (1,2)
       );
结果是:

Customer_id   1_sales 1_bill 2_sales 2_bill 
1             10      10     20      20       
但我需要先看销售栏,再看账单栏

Customer_id   1_sales 2_sales 1_bill 2_bill 
1             10      20      10      20       
我怎样才能得到这个订单


编辑:我需要以动态方式执行此操作,因为我要将其用于经过身份验证的报告

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

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

大概是这样的:

select customer_id, "1_SALES", "2_SALES", "1_BILL", "2_BILL" [ ... ]
from   ...
..........

执行此操作时,还可以为列提供更多标准名称(因此它们不以数字开头,因此不需要双引号)。

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

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 
为了使这些列有序

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

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;
/
其中,表被假定为创建为

CREATE TABLE t
(
  customer_id INT,
  month       INT,
  sales_amt   NUMBER,
  bill_amt    NUMBER
)
然后从SQL开发人员控制台调用函数

SQL> DECLARE
    res SYS_REFCURSOR;
BEGIN
   :res := Get_Pivoted_Sales;
END;
/

SQL> PRINT res;

这是一种动态的方式吗?我使用月份作为日期,3年前的数据采用“YYYYMM”格式。我不想每年都手工做这个。