【问题标题】:Transform columns to rows - Pivot not working (ORACLE 11g)将列转换为行 - 枢轴不起作用 (ORACLE 11g)
【发布时间】:2015-09-10 14:38:24
【问题描述】:

我无法在表格上使用数据透视表。

查询:

SELECT CONCAT(LTRIM(P_NAME), CONCAT(' ', LTRIM(P_LASTNAME))) AS FULL_NAME FROM PERSON WHERE PERSON_ID = XX

结果:

FULL_NAME Maria Tasso Tagliari Lucas O.R. da Silva Guilherme O. Ribeiro da Silva Cristina De Oliveira Inês De Oliveira Luiz Ribeiro da Silva Gabriela de Aro Ribeiro da Silva

我需要在一行中返回所有这些名称,每个名称对应一列。列名无关紧要(FULL_NAME01、FULL_NAME02 .....)

我在使用数据透视表时遇到问题,因为我没有可以使用聚合函数的列。

有人可以帮我解决这个问题吗?

谢谢!!

【问题讨论】:

    标签: oracle plsql oracle11g pivot pivot-table


    【解决方案1】:

    尝试类似:

    with x as (
        select 1 as person_id, 'JOE BLOW' as fullname from dual
        union all
        select 1 as person_id, 'JOE SNOW' as fullname from dual
        union all
        select 2 as person_id, 'JANE DOE' as fullname from dual
    )
    select *
    from 
    (
     select person_id, fullname, row_number() over (partition by person_id order by fullname) rnum
     from x
    )
    pivot (
      max(fullname) 
      -- allow up to 5 names per person
      for rnum in (1 name1,2 name2,3 name3,4 name4,5 name5)
    );
    

    输出:

    PERSON_ID   NAME1   NAME2   NAME3   NAME4   NAME5
    1   JOE BLOW    JOE SNOW            
    2   JANE DOE    
    

    编辑: 如果您想要基于附加 STATUS 字段的单独行,每个人每个状态最多 5 个名称,那么您将拥有:

    with x as (
        select 1 as person_id, 'JOE BLOW' as fullname, 'Active' as status from dual
        union all
        select 1 as person_id, 'JOE SNOW' as fullname, 'Inactive' as status from dual
        union all
        select 1 as person_id, 'JOE ROGAN' as fullname, 'Inactive' as status from dual
        union all
        select 2 as person_id, 'JANE DOE' as fullname, 'Active' as status from dual
    )
    select *
    from 
    (
     select person_id, fullname, status, row_number() over (partition by person_id, status order by fullname) rnum
     from x
    )
    pivot (
      max(fullname) 
      -- allow up to 5 names per person
      for rnum in (1 name1,2 name2,3 name3,4 name4,5 name5)
    );
    

    输出:

    PERSON_ID   STATUS  NAME1   NAME2   NAME3   NAME4   NAME5
    1   Active  JOE BLOW                
    1   Inactive    JOE ROGAN   JOE SNOW            
    2   Active  JANE DOE    
    

    所以 person_id=1 有 1 个活跃的名字和 2 个不活跃的名字。

    【讨论】:

    • 它在这里工作!但是如果我不知道 ID 的数量呢?我尝试使用 IN (ANY) 但它没有用。谢谢帮忙!!
    • 很高兴它对你有用。不确定“如果我不知道 ID 的数量”是什么意思。你的意思是“person_id”?这可能是 varchar 或您的系统使用的任何内容。如果您的意思是可以找到多少个不同的名称,则必须设置一个硬限制(5 或 10 或其他)以在枢轴中创建那么多列(无论如何对于非 xml 枢轴)
    【解决方案2】:

    为了更好地说明我正在尝试做的事情,我更改了我们使用的示例。 我有一张表,其中人们按状态类别分隔,我需要将它们放在按状态分组的一行中,但在具有相同状态的人的情况下,只选择一个。 例如,我使用了以下查询:

    with x as ( select 'JOE BLOW' as fullname, '1' as status from dual union all select 'JOE SNOW' as fullname, '1' as status from dual union all select 'JANE DOE' as fullname, '2' as status from dual) select * from ( select fullname, status from x ) pivot ( max(fullname) for status in (1, 2, 3, 4, 5) );

    结果如下:

    1           2           3           4           5           
    JOE SNOW    JANE DOE
    

    如您所见,有两条状态为“1”的记录,但只返回了一条。

    另外一个问题,我们可以参数化IN()子句的内容吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-02
      • 1970-01-01
      相关资源
      最近更新 更多