嗨我想在比较来自另一个视图的行集后从视图中获取序列 ID。 我可以执行 listagg 并按序列 ID 进行分组,并将该 listagg 与其他视图匹配。但是还有其他选择吗? View 1 的 seq_id 顺序为 0,1,2,3,4.... 并且 pattern id 也是有序的。我们可以让 ROW_NUMBER()over() 有模式 id 的排序
WITH view1(seq_id, pattern_id,rnum) AS (SELECT 0 , 1 ,1 FROM dual UNION
SELECT 0 , 2,2 FROM dual UNION
SELECT 0 , 3,3 FROM dual UNION
SELECT 0 , 4,4 FROM dual UNION
SELECT 1 , 3,5 FROM dual UNION
SELECT 1 , 4,6 FROM dual UNION
SELECT 1 , 1,7 FROM dual UNION
SELECT 1 , 2,8 FROM dual UNION
SELECT 2 , 2,9 FROM dual UNION
SELECT 2 , 4,10 FROM dual UNION
SELECT 2 , 1,11 FROM dual UNION
SELECT 2 , 3,12 FROM dual )
SELECT * FROM view1 order by rnum;
例子:
查看 1
seq id pattern
------ -------
0 1
0 2
0 3
0 4
1 3
1 4
1 1
1 2
2 2
2 3
2 5
2 1
View 2 有另一列 pk_id,它是像 rownum 一样的唯一序列。始终以 1
开头 pk_id pattern id
------ ------------
1 3
2 4
3 1
4 2
View 1 的预期输出
seq id
------
1
listagg
看起来是一个相当相关的方法。另一种方法是使用关系除法技术:
select v1.seq_id
from (
select v1.*,
row_number() over(partition by seq_id order by rnum) pk_id
from view1 v1
) v1
inner join view2 v2
on v2.pattern_id = v1.pattern_id
and v2.pk_id = v1.pk_id
group by v1.seq_id
having count(*) = (select count(*) from view2)
如果你想排除包含比参考更多模式的seq_ids,我们可以
left join
代替:
select v1.seq_id
from (
select v1.*,
row_number() over(partition by seq_id order by rnum) pk_id
from view1 v1
) v1
left join view2 v2
on v2.pattern_id = v1.pattern_id
and v2.pk_id = v1.pk_id
group by v1.seq_id
having count(*) = (select count(*) from view2)
and count(*) = count(v2.pk_id)
可以使用
ROW_NUMBER
解析函数对view1
中的每个序列进行索引,然后将其与view2
进行比较,找到匹配序列所有行的序列:
SELECT seq_id,
MIN(rnum) AS pattern_start
FROM ( SELECT v1.*,
ROW_NUMBER() OVER (PARTITION BY seq_id ORDER BY rnum) AS rn,
COUNT(*) OVER (PARTITION BY seq_id) AS num_patterns
FROM view1 v1
) v1
INNER JOIN (
SELECT v2.*,
COUNT(*) OVER () AS num_patterns
FROM view2 v2
) v2
ON v1.rn = v2.pk_id
AND v1.pattern_id = v2.pattern_id
AND v1.num_patterns = v2.num_patterns
GROUP BY seq_id
HAVING COUNT(*) = MAX(v1.num_patterns);
其中,对于示例数据:
CREATE VIEW view1 (seq_id, pattern_id, rnum) AS
SELECT 0, 1, 1 FROM dual UNION ALL
SELECT 0, 2, 2 FROM dual UNION ALL
SELECT 0, 3, 3 FROM dual UNION ALL
SELECT 0, 4, 4 FROM dual UNION ALL
SELECT 1, 3, 5 FROM dual UNION ALL
SELECT 1, 4, 6 FROM dual UNION ALL
SELECT 1, 1, 7 FROM dual UNION ALL
SELECT 1, 2, 8 FROM dual UNION ALL
SELECT 2, 2, 9 FROM dual UNION ALL
SELECT 2, 4, 10 FROM dual UNION ALL
SELECT 2, 1, 11 FROM dual UNION ALL
SELECT 2, 3, 12 FROM dual
ORDER BY 3;
CREATE VIEW view2 (pk_id, pattern_id) AS
SELECT 1, 3 FROM dual UNION ALL
SELECT 2, 4 FROM dual UNION ALL
SELECT 3, 1 FROM dual UNION ALL
SELECT 4, 2 FROM dual
ORDER BY 1;
输出:
序列号 | PATTERN_START |
---|---|
1 | 5 |