【问题标题】:Pivot Data into New Column Names - Oracle SQL将数据透视到新的列名 - Oracle SQL
【发布时间】:2021-04-21 20:46:55
【问题描述】:

在 Oracle SQL 中工作,我有以下数据集:

我的目标是将它放入一个看起来像这样的数据集,我假设我将不得不使用某种形式的数据透视函数,但我不确定如何创建新的列名'在同一步骤中尚不存在:

我只提供了我的全部数据集的一个示例,会有大量 INDIV_ID 记录具有不同数量的可能购买日期(即,并非每个 INDIV_ID 都会有 10 个购买日期。有些可能有更多,有些可能有更少)

提前谢谢你,
尼克

【问题讨论】:

  • 您开始使用的结构适用于不同数量的日期。您的目标结构不是。这是一种 SQL 反模式,这在 SQL 中是不正确的。 SQL 不是 Excel,坚持规范化(原始)数据结构,这是专为 SQL 使用而设计的。

标签: sql oracle pivot


【解决方案1】:

如果您知道所需的列数,则可以这样做:

select indiv_id,
       max(case when seqnum = 1 then prch_dt end) as dt_1,
       max(case when seqnum = 2 then prch_dt end) as dt_2,
       . . .
from (select t.*,
             row_number() over (partition by indiv_id order by prch_dt) as seqnum
      from t
     ) t
group by indiv_id;

如果不知道列数,则需要使用动态SQL——相当麻烦。

或者,您可以将值聚合到单个分隔字符串中:

select indiv_id,
       list_agg(prch_dt, ',') within group (order by prch_dt)
from (select t.*,
             row_number() over (partition by indiv_id order by prch_dt) as seqnum
      from t
     ) t
group by indiv_id;

【讨论】:

    【解决方案2】:

    您可以使用条件聚合的方式创建一个选择语句字符串来旋转这些列,同时通过使用ROW_NUMBER() 函数对每个单独的日期进行枚举,以便动态分配不同的整数值,即使存在相等的日期存储函数中的值,该函数返回 SYS_REFCURSOR 类型的值,例如

    CREATE OR REPLACE FUNCTION Fn_Pivot_Table RETURN SYS_REFCURSOR IS
      v_recordset SYS_REFCURSOR;
      v_sql       VARCHAR2(32767);
      v_cols      VARCHAR2(32767);   
    BEGIN
      SELECT LISTAGG( 'MAX(CASE WHEN rn = '||rn||' THEN prch_dt END ) AS  "Date_'||rn||'"'  , ',')
                       WITHIN GROUP ( ORDER BY rn )
                     
        INTO v_cols
        FROM ( SELECT prch_dt,ROW_NUMBER() OVER (PARTITION BY indiv_id ORDER BY prch_dt) AS rn FROM t );
          
      v_sql :='SELECT indiv_id,'|| v_cols ||
              '  FROM ( SELECT t.*,ROW_NUMBER() OVER (PARTITION BY indiv_id ORDER BY prch_dt) AS rn FROM t )
                GROUP BY indiv_id';
    
      OPEN v_recordset FOR v_sql;
      RETURN v_recordset;
    END;
    /
    

    其中t 表示您需要对其进行透视的表购买日期值。

    然后从 SQL Developer 的控制台调用该函数

    SQL> DECLARE
        result SYS_REFCURSOR;
    BEGIN
       :result := Fn_Pivot_Table;
    END;
    /
    
    SQL> PRINT result;
    

    【讨论】:

    • 有趣,这似乎是这工作的第一部分。但是当我尝试从 SQL Dev 的控制台调用该函数时,我得到了未知的命令错误
    • 嗨@Ciccotelli412,你遇到了什么错误?
    猜你喜欢
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2016-04-15
    相关资源
    最近更新 更多