选择以获取空值行以进行连接

时间:2016-01-28 09:35:25

标签: oracle select with-statement listagg

这是表格(TABLE_1)

select * from TABLE_1;

PK_1 PK_2 PK_3 PK_4 PK_5 COL_1 COL_2 COL_3
---- ---- ---- ---- ---- ----- ----- -----
aaa  bbb  ccc  ddd  1    1     2     3    
aaa  bbb  ccc  ddd  2    4     5     6    
aaa  bbb  ccc  ddd  3    7     8     9    

我想要这样的输出:

PK_1 PK_2 PK_3 PK_4 AGGREGATE
---- ---- ---- ---- -------------------
aaa  bbb  ccc  ddd  123 456 789 000 000

所以这就是我到目前为止所尝试的:

SELECT 
    PK_1 ,PK_2 ,PK_3 ,PK_4 ,
    listagg (COL_1 || COL_2 || COL_3 , ' ')within group (ORDER BY PK_1 ,PK_2 ,PK_3 ,PK_4 , PK_5) as "AGGREGATE"
FROM 
    TABLE_1
GROUP BY
    PK_1 ,PK_2 ,PK_3 ,PK_4
;

PK_1 PK_2 PK_3 PK_4 AGGREGATE
---- ---- ---- ---- -----------
aaa  bbb  ccc  ddd  123 456 789 

问题是我没有收到000 000输出,因为第4行和第5行缺少数据。如果根据AGGREGATE缺少相应的行,我需要此查询以XXX XXX XXX XXX XXX格式000格式输出PK_5列。

请帮助..我认为这需要WITH CLAUSE,但我无法实施。

4 个答案:

答案 0 :(得分:2)

假设您期望每个最多5行(pk_1,pk_2,pk_3,pk_4),那么以下(使用partition outer join)应该可以做到这一点:

fetchRequest.fetchLimit = 1
var highestSortDescriptor : NSSortDescriptor = NSSortDescriptor(key: "rasScore", ascending: false)
fetchRequest.sortDescriptors = [highestSortDescriptor]

N.B。如果您的pk_5列没有开始为每个行编号1(pk_1,pk_2,pk_3,pk_4),那么您需要使用col aggregate format a20; with table_1 as (select 'aaa' pk_1, 'bbb' pk_2, 'ccc' pk_3, 'ddd' pk_4, 1 pk_5, 1 col_1, 2 col_2, 3 col_3 from dual union all select 'aaa' pk_1, 'bbb' pk_2, 'ccc' pk_3, 'ddd' pk_4, 2 pk_5, 4 col_1, 5 col_2, 6 col_3 from dual union all select 'aaa' pk_1, 'bbb' pk_2, 'ccc' pk_3, 'ddd' pk_4, 3 pk_5, 7 col_1, 8 col_2, 9 col_3 from dual), -- end of mimicking your table table_1; you wouldn't need this subquery as you already have the table. dummy as (select level id from dual connect by level <= 5) select pk_1, pk_2, pk_3, pk_4, listagg (nvl(col_1, 0)||nvl(col_2, 0)||nvl(col_3, 0), ' ') within group (order by pk_1, pk_2, pk_3, pk_4, pk_5) aggregate from dummy d left outer join table_1 t1 partition by (t1.pk_1, t1.pk_2, t1.pk_3, t1.pk_4) on (t1.pk_5 = d.id) group by pk_1, pk_2, pk_3, pk_4; PK_1 PK_2 PK_3 PK_4 AGGREGATE ---- ---- ---- ---- -------------------- aaa bbb ccc ddd 123 456 789 000 000 分析函数生成要加入的数字列表对虚拟表:

row_number()

答案 1 :(得分:1)

此查询涵盖的每个案例:在任何位置都缺少值,而不仅仅是在最后。它假定&#34; AGGREGATE&#34;将永远有5个部分。

WITH CTE1 AS
(
  SELECT * FROM 
  (SELECT LEVEL PK_5 FROM DUAL CONNECT BY LEVEL <=5) 
  CROSS JOIN 
  (SELECT DISTINCT PK_1, PK_2, PK_3, PK_4 FROM TABLE_1)
), CTE2 AS
(
SELECT PK_1,PK_2,PK_3,PK_4,PK_5 FROM CTE1
)
SELECT PK_1,PK_2,PK_3,PK_4,
LISTAGG (NVL(COL_1, 0) || NVL(COL_2, 0) || NVL(COL_3, 0) , ' ') WITHIN GROUP (ORDER BY PK_1 ,PK_2 ,PK_3 ,PK_4 , PK_5) AS "AGGREGATE"
FROM CTE2 LEFT JOIN TABLE_1 USING(PK_1,PK_2,PK_3,PK_4,PK_5)
GROUP BY
PK_1 ,PK_2 ,PK_3 ,PK_4;

感谢Boneist启动分区外连接。这确实是更好的解决方案。

WITH CTE AS
(
  SELECT * FROM TABLE_1 PARTITION BY (PK_1,PK_2,PK_3,PK_4)
  RIGHT OUTER JOIN (SELECT LEVEL NR FROM DUAL CONNECT BY LEVEL <=5) GEN
  ON GEN.NR = TABLE_1.PK_5
)
SELECT PK_1,PK_2,PK_3,PK_4,
LISTAGG(NVL(COL_1,0) || NVL(COL_2,0) || NVL(COL_3,0), ' ') WITHIN GROUP(ORDER BY PK_1) "AGGREGATE"
FROM CTE 
GROUP BY PK_1, PK_2, PK_3, PK_4;

答案 2 :(得分:0)

这应该有效:

select PK_1 ,PK_2 ,PK_3 ,PK_4, DECODE(length(T.AGG), 11 , CONCAT(T.AGG , ' 000 000'), 15, CONCAT(T.AGG , ' 000'), T.AGG)
from (SELECT 
    PK_1 ,PK_2 ,PK_3 ,PK_4 ,
    listagg (COL_1 || COL_2 || COL_3 , ' ')within group (ORDER BY PK_1 ,PK_2 ,PK_3 ,PK_4 , PK_5) as "AGG"
FROM 
    TABLE_1
GROUP BY
    PK_1 ,PK_2 ,PK_3 ,PK_4
) t;

我写的是缺少2行的情况。您可以编辑解码功能以包含所有情况。

答案 3 :(得分:0)

我从你的理解中了解到,无论何时你在列Col_1,Col_2和Col_3的行中都为null,它应该被视为0并且输出应该包括000.如果是这种情况,那么下面的查询将给出你的输出寻找。

With a as 
(Select PK_1,PK_2, PK_3, PK_4, PK_5,
       case when col_1 is null then '0' else col_1 end as col_1,
       case when col_2 is null then '0' else col_2 end as col_2,
       case when col_3 is null then '0' else col_3 end as col_3
from table1) 
SELECT PK_1,PK_2,PK_3,PK_4,
     LISTAGG (col_1 || col_2 || col_3, ' ') within group (ORDER BY PK_1 ,PK_2 ,PK_3 ,PK_4 , PK_5) as "AGGREGATE"
    From a
GROUP BY
    PK_1 ,PK_2 ,PK_3 ,PK_4;