这是表格(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
,但我无法实施。
答案 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;