Oracle SQL 显示来自相同 table 的匹配数据
Oracle SQL showing matching data from same table
你好,我有关注table:
Id Code Acct
=================
1 002 123456
1 004 123456
2 004 456789
2 004 123456
3 001 3456456
4 005 975236
5 006 146387
6 004 0054321
6 010 123456
7 008 165432
7 007 987654
7 002 123456
我需要通过以下方式找到匹配 Code
和 Acct
的 ID:
Code Acct Id1 Id2
=====================
002 123456 1 7
004 123456 1 2
Self-join(第 1 - 15 行代表示例数据;您需要的查询从第 16 行开始):
SQL> with test (id, code, acct) as
2 (select
3 1, '002', 123456 from dual union all select
4 1, '004', 123456 from dual union all select
5 2, '004', 456789 from dual union all select
6 2, '004', 123456 from dual union all select
7 3, '001', 3456456 from dual union all select
8 4, '005', 975236 from dual union all select
9 5, '006', 146387 from dual union all select
10 6, '004', 0054321 from dual union all select
11 6, '010', 123456 from dual union all select
12 7, '008', 165432 from dual union all select
13 7, '007', 987654 from dual union all select
14 7, '002', 123456 from dual
15 )
16 select a.code, a.acct, a.id id1, b.id id2
17 from test a join test b on a.code = b.code
18 and a.acct = b.acct
19 and a.id > b.id
20 order by code, acct;
COD ACCT ID1 ID2
--- ---------- ---------- ----------
002 123456 7 1
004 123456 2 1
SQL>
如果您有任意数量的重复项(即可能超过 2 个),或者您希望单次通过 table,您可以使用一些解析 SQL
SQL> with t as
2 (
3 select 1 id, 002 code, 123456 acct from dual union all
4 select 1, 004 , 123456 acct from dual union all
5 select 2, 004 , 456789 acct from dual union all
6 select 2, 004 , 123456 acct from dual union all
7 select 3, 001 , 3456456 acct from dual union all
8 select 4, 005 , 975236 acct from dual union all
9 select 5, 006 , 146387 acct from dual union all
10 select 6, 004 , 0054321 acct from dual union all
11 select 6, 010 , 123456 acct from dual union all
12 select 7, 008 , 165432 acct from dual union all
13 select 7, 007 , 987654 acct from dual union all
14 select 7, 002 , 123456 acct from dual
15 ),
16 dups as (
17 select t.*,
18 count(*) over ( partition by code,acct ) as dup_cnt
19 from t
20 )
21 select code, acct, listagg(id,',') within group ( order by id) as id_list
22 from dups
23 where dup_cnt > 1
24 group by code, acct;
CODE ACCT ID_LIST
---------- ---------- ------------------------------
2 123456 1,7
4 123456 1,2
您可以先使用 LISTAGG
然后 REGEXP_SUBSTR
。
SELECT CODE,
ACCT,
REGEXP_SUBSTR (CONCT,
'[^,]+',
1,
1)
ID1,
REGEXP_SUBSTR (CONCT,
'[^,]+',
1,
2)
AS ID2
FROM (WITH MAIN
AS (SELECT 1 AS ID, '002' AS CODE, '123456' AS ACCT FROM DUAL
UNION ALL
SELECT 1 AS ID, '004' AS CODE, '123456' AS ACCT FROM DUAL
UNION ALL
SELECT 2 AS ID, '004' AS CODE, '456789' AS ACCT FROM DUAL
UNION ALL
SELECT 2 AS ID, '004' AS CODE, '123456' AS ACCT FROM DUAL
UNION ALL
SELECT 3 AS ID, '001' AS CODE, '3456456' AS ACCT FROM DUAL
UNION ALL
SELECT 4 AS ID, '005' AS CODE, '975236' AS ACCT FROM DUAL
UNION ALL
SELECT 5 AS ID, '006' AS CODE, '146387' AS ACCT FROM DUAL
UNION ALL
SELECT 6 AS ID, '004' AS CODE, '0054321' AS ACCT FROM DUAL
UNION ALL
SELECT 6 AS ID, '010' AS CODE, '123456' AS ACCT FROM DUAL
UNION ALL
SELECT 7 AS ID, '008' AS CODE, '165432' AS ACCT FROM DUAL
UNION ALL
SELECT 7 AS ID, '007' AS CODE, '987654' AS ACCT FROM DUAL
UNION ALL
SELECT 7 AS ID, '002' AS CODE, '123456' AS ACCT FROM DUAL)
SELECT A.CODE,
A.ACCT,
LISTAGG (A.ID, ',') WITHIN GROUP (ORDER BY A.ID) AS CONCT
FROM MAIN A
GROUP BY A.CODE, A.ACCT)
你可以试试这个。
WITH CTE1 AS (
SELECT * FROM TABLE1 WHERE (CODE, ACCT) IN (
SELECT CODE, ACCT FROM (
select count(1), CODE, ACCT FROM TABLE1
GROUP BY CODE, ACCT HAVING COUNT(1) > 1) T))
SELECT X.ID ID1, Y.ID ID2, X.CODE, X.ACCT FROM CTE1 X, CTE1 Y WHERE X.CODE = Y.CODE AND X.ACCT
= Y.ACCT AND X.ID > Y.ID;
只需使用聚合:
select code, account, min(id), max(id)
from t
group by code, account
having count(*) > 1;
注意:这只有 returns 两个匹配的示例 ID。如果你想要所有这些,你可以使用 listagg()
:
select code, account, listagg(id, ',') within group (order by id) as ids
from t
group by code, account
having count(*) > 1;
你好,我有关注table:
Id Code Acct
=================
1 002 123456
1 004 123456
2 004 456789
2 004 123456
3 001 3456456
4 005 975236
5 006 146387
6 004 0054321
6 010 123456
7 008 165432
7 007 987654
7 002 123456
我需要通过以下方式找到匹配 Code
和 Acct
的 ID:
Code Acct Id1 Id2
=====================
002 123456 1 7
004 123456 1 2
Self-join(第 1 - 15 行代表示例数据;您需要的查询从第 16 行开始):
SQL> with test (id, code, acct) as
2 (select
3 1, '002', 123456 from dual union all select
4 1, '004', 123456 from dual union all select
5 2, '004', 456789 from dual union all select
6 2, '004', 123456 from dual union all select
7 3, '001', 3456456 from dual union all select
8 4, '005', 975236 from dual union all select
9 5, '006', 146387 from dual union all select
10 6, '004', 0054321 from dual union all select
11 6, '010', 123456 from dual union all select
12 7, '008', 165432 from dual union all select
13 7, '007', 987654 from dual union all select
14 7, '002', 123456 from dual
15 )
16 select a.code, a.acct, a.id id1, b.id id2
17 from test a join test b on a.code = b.code
18 and a.acct = b.acct
19 and a.id > b.id
20 order by code, acct;
COD ACCT ID1 ID2
--- ---------- ---------- ----------
002 123456 7 1
004 123456 2 1
SQL>
如果您有任意数量的重复项(即可能超过 2 个),或者您希望单次通过 table,您可以使用一些解析 SQL
SQL> with t as
2 (
3 select 1 id, 002 code, 123456 acct from dual union all
4 select 1, 004 , 123456 acct from dual union all
5 select 2, 004 , 456789 acct from dual union all
6 select 2, 004 , 123456 acct from dual union all
7 select 3, 001 , 3456456 acct from dual union all
8 select 4, 005 , 975236 acct from dual union all
9 select 5, 006 , 146387 acct from dual union all
10 select 6, 004 , 0054321 acct from dual union all
11 select 6, 010 , 123456 acct from dual union all
12 select 7, 008 , 165432 acct from dual union all
13 select 7, 007 , 987654 acct from dual union all
14 select 7, 002 , 123456 acct from dual
15 ),
16 dups as (
17 select t.*,
18 count(*) over ( partition by code,acct ) as dup_cnt
19 from t
20 )
21 select code, acct, listagg(id,',') within group ( order by id) as id_list
22 from dups
23 where dup_cnt > 1
24 group by code, acct;
CODE ACCT ID_LIST
---------- ---------- ------------------------------
2 123456 1,7
4 123456 1,2
您可以先使用 LISTAGG
然后 REGEXP_SUBSTR
。
SELECT CODE,
ACCT,
REGEXP_SUBSTR (CONCT,
'[^,]+',
1,
1)
ID1,
REGEXP_SUBSTR (CONCT,
'[^,]+',
1,
2)
AS ID2
FROM (WITH MAIN
AS (SELECT 1 AS ID, '002' AS CODE, '123456' AS ACCT FROM DUAL
UNION ALL
SELECT 1 AS ID, '004' AS CODE, '123456' AS ACCT FROM DUAL
UNION ALL
SELECT 2 AS ID, '004' AS CODE, '456789' AS ACCT FROM DUAL
UNION ALL
SELECT 2 AS ID, '004' AS CODE, '123456' AS ACCT FROM DUAL
UNION ALL
SELECT 3 AS ID, '001' AS CODE, '3456456' AS ACCT FROM DUAL
UNION ALL
SELECT 4 AS ID, '005' AS CODE, '975236' AS ACCT FROM DUAL
UNION ALL
SELECT 5 AS ID, '006' AS CODE, '146387' AS ACCT FROM DUAL
UNION ALL
SELECT 6 AS ID, '004' AS CODE, '0054321' AS ACCT FROM DUAL
UNION ALL
SELECT 6 AS ID, '010' AS CODE, '123456' AS ACCT FROM DUAL
UNION ALL
SELECT 7 AS ID, '008' AS CODE, '165432' AS ACCT FROM DUAL
UNION ALL
SELECT 7 AS ID, '007' AS CODE, '987654' AS ACCT FROM DUAL
UNION ALL
SELECT 7 AS ID, '002' AS CODE, '123456' AS ACCT FROM DUAL)
SELECT A.CODE,
A.ACCT,
LISTAGG (A.ID, ',') WITHIN GROUP (ORDER BY A.ID) AS CONCT
FROM MAIN A
GROUP BY A.CODE, A.ACCT)
你可以试试这个。
WITH CTE1 AS (
SELECT * FROM TABLE1 WHERE (CODE, ACCT) IN (
SELECT CODE, ACCT FROM (
select count(1), CODE, ACCT FROM TABLE1
GROUP BY CODE, ACCT HAVING COUNT(1) > 1) T))
SELECT X.ID ID1, Y.ID ID2, X.CODE, X.ACCT FROM CTE1 X, CTE1 Y WHERE X.CODE = Y.CODE AND X.ACCT
= Y.ACCT AND X.ID > Y.ID;
只需使用聚合:
select code, account, min(id), max(id)
from t
group by code, account
having count(*) > 1;
注意:这只有 returns 两个匹配的示例 ID。如果你想要所有这些,你可以使用 listagg()
:
select code, account, listagg(id, ',') within group (order by id) as ids
from t
group by code, account
having count(*) > 1;