Sql 在oracle中透视和排序多个列
我知道如何在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
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”格式。我不想每年都手工做这个。