【问题标题】:PL/SQL finding and let row wise duplicatesPL/SQL 查找并让行明智的重复
【发布时间】:2020-07-28 13:32:30
【问题描述】:

我有一个有 10 列的表。看起来像这样

NULL 1 1 NULL NULL NULL NULL NULL 2 NULL
1 NULL NULL 2 NULL 1 NULL NULL 2 NULL
NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL NULL NULL 2 NULL

我需要一个返回以下内容的 SQL 查询:(不同的行)

1 2
1 2
NULL
2

【问题讨论】:

  • 什么版本的Oracle?
  • 我不明白上述输出的逻辑是什么,有些行包含空值有些不包含空值,这不是行虎钳不同,而是列虎钳
  • @GordonLinoff 18c
  • @HimanshuAhuja 我希望每行除 NULL 之外的所有不同值

标签: sql oracle plsql distinct oracle18c


【解决方案1】:

您可以按如下方式使用hiearchy query

SELECT LISTAGG(E, ' ') WITHIN GROUP( ORDER BY E )
FROM
    ( SELECT DISTINCT
            ROWID AS RID,
            DECODE(COLUMN_VALUE, 1, COL1, 2, COL2, 3, COL3, 4, COL4 ..., 10, COL10) AS E
        FROM YOUR_TABLE
             CROSS JOIN TABLE ( CAST(MULTISET(
                SELECT LEVEL
                  FROM DUAL
                CONNECT BY LEVEL <= 10 ) AS SYS.ODCINUMBERLIST) )
    )
GROUP BY RID;

【讨论】:

    【解决方案2】:

    您可以将UNPIVOT 列转换为行(并保留NULL 值),然后过滤以保留DISTINCT 行,然后将行聚合成一个字符串,忽略NULL 值,除非它们都是@ 987654326@:

    SELECT LISTAGG( value, ' ' ) WITHIN GROUP ( ORDER BY value ) AS vals
    FROM   (
      SELECT DISTINCT
             rn,
             value,
             COUNT(value) OVER ( PARTITION BY rn ) AS num_values
      FROM   (
        SELECT ROWNUM AS rn,
               t.*
        FROM   table_name t
      )
      UNPIVOT INCLUDE NULLS (
        value FOR key IN ( col1, col2, col3, col4, col5, col6, col7, col8, col9, col10 )
      )
    )
    WHERE num_values = 0
    OR    value IS NOT NULL
    GROUP BY rn
    

    因此,对于您的示例数据:

    CREATE TABLE table_name (
      col1 NUMBER,
      col2 NUMBER,
      col3 NUMBER,
      col4 NUMBER,
      col5 NUMBER,
      col6 NUMBER,
      col7 NUMBER,
      col8 NUMBER,
      col9 NUMBER,
      col10 NUMBER
    );
    
    INSERT INTO table_name
    SELECT NULL,    1,    1, NULL, NULL, NULL, NULL, NULL,    2, NULL FROM DUAL UNION ALL
    SELECT    1, NULL, NULL,    2, NULL,    1, NULL, NULL,    2, NULL FROM DUAL UNION ALL
    SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM DUAL UNION ALL
    SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,    2, NULL FROM DUAL;
    

    这个输出:

    |瓦尔斯 | | :--- | | 1 2 | | 1 2 | | | | 2 |

    db小提琴here

    【讨论】:

    • 你的逻辑怎么和我的不一样?
    • @HimanshuAhuja 您正在尝试使用 LISTAGG( DISTINCT ... ),这在 Oracle 18c 上的语法无效;在使用LISTAGG 之前,我有一个子查询来执行DISTINCT 过滤,并且当所有列都是NULL 时,我还有额外的过滤来保持NULL 的值。
    【解决方案3】:

    如果这有助于尝试将列取消旋转为 1,请尝试以下操作,以消除空值,在取消旋转然后通过分组聚合之前为每个先前的选择保留 rowid

        Select op from (Select rn, 
         listagg(distinct col, 
           ',') within group (order by 
             col) as  op from
       (  Select *, row_number() over(
        Partition by col1, col2.. Col10 order by
       ..) rn
         from table
        UnPIVOT 
      (COL, num) IN   ( (COL1, COL2,... 
         Col10), rn)) 
    
       ) where col is not null group by 
      rn) 
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    相关资源
    最近更新 更多