PL/SQL 查找并让行重复
PL/SQL finding and let row wise duplicates
我有一个包含 10 列的 table。看起来像这样
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 查询 returns 这个:(不同的行)
1 2
1 2
NULL
2
您可以按如下方式使用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;
如果这有助于尝试将列反透视为 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)
您可以 UNPIVOT
列到行(并保留 NULL
值),然后过滤以保留 DISTINCT
行,然后将行聚合成一个字符串,忽略 NULL
值,除非它们都是 NULL
:
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;
这输出:
| VALS |
| :--- |
| 1 2 |
| 1 2 |
| null |
| 2 |
db<>fiddle here
我有一个包含 10 列的 table。看起来像这样
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 查询 returns 这个:(不同的行)
1 2
1 2
NULL
2
您可以按如下方式使用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;
如果这有助于尝试将列反透视为 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)
您可以 UNPIVOT
列到行(并保留 NULL
值),然后过滤以保留 DISTINCT
行,然后将行聚合成一个字符串,忽略 NULL
值,除非它们都是 NULL
:
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;
这输出:
| VALS | | :--- | | 1 2 | | 1 2 | | null | | 2 |
db<>fiddle here