我有两个表A和B.两个都有相同的结构。我们在这两者之间找到匹配的记录。这是脚本
CREATE TABLE HRS.A
(
F_1 NUMBER(5,0),
F_2 NUMBER(5,0),
F_3 NUMBER(5,0)
);
CREATE TABLE HRS.B
(
F_1 NUMBER(5,0),
F_2 NUMBER(5,0),
F_3 NUMBER(5,0)
);
INSERT INTO hrs.a VALUES (1,1000,2000);
INSERT INTO hrs.a VALUES (2,1100,8000);
INSERT INTO hrs.a VALUES (3,4000,3000);
INSERT INTO hrs.a VALUES (4,2000,5000);
INSERT INTO hrs.a VALUES (5,5000,3000);
INSERT INTO hrs.a VALUES (6,6000,6000);
INSERT INTO hrs.a VALUES (7,3000,7000);
INSERT INTO hrs.a VALUES (8,1100,9000);
INSERT INTO hrs.b VALUES (1,4000,2000);
INSERT INTO hrs.b VALUES (2,6000,8000);
INSERT INTO hrs.b VALUES (3,1000,3000);
INSERT INTO hrs.b VALUES (4,2000,5000);
INSERT INTO hrs.b VALUES (5,8000,3000);
INSERT INTO hrs.b VALUES (6,1100,6000);
INSERT INTO hrs.b VALUES (7,5000,7000);
INSERT INTO hrs.b VALUES (8,1000,9000);
查找匹配记录
SELECT a.F_1 A_F1, b.F_1 B_F1 FROM HRS.A, HRS.B WHERE A.F_2 = B.F_2
结果
A_F1 B_F1
3 1
6 2
1 3
4 4
8 6
2 6
5 7
1 8
现在我想分别删除两列中的重复条目,例如1在A_F1中重复(不管B_F1),因此将删除行#3(1-3)和8(1-8)。现在6在B_F1中重复(不管A_F1),因此将删除行#5(8-6)和6(2-6)。最终结果应该是
A_F1 B_F1
3 1
6 2
4 4
5 7
现在最重要的部分,这两个表包含 500,000条记录。我首先找到并将这些匹配记录插入到临时表中,然后从第一列中删除重复,然后从第二列中删除,然后从临时表中选择所有重复。这太慢了。我怎样才能更快地实现这一目标?
编辑#1
我多次执行以下语句,在每个表中生成4096条记录
INSERT INTO hrs.a SELECT F_1 + 1, F_2 + 1, 0 FROM hrs.a;
INSERT INTO hrs.b SELECT F_1 + 1, F_2 + 1, 0 FROM hrs.b;
现在我执行了所有答案并找到了这些
Rachcha 9.11 secs OK
techdo 1.14 secs OK
Gentlezerg 577 msecs WRONG RESULTS
Justin 218 msecs OK
即使@Justin花了37.69秒,每张65,536条记录(总计= 131,072)
等待更多优化答案,因为实际记录数为1,000,000:)
以下是基于贾斯汀答案的查询执行计划
答案 0 :(得分:3)
请尝试:
select A_F1, B_F1 From(
SELECT a.F_1 A_F1, b.F_1 B_F1,
count(*) over (partition by a.F_1 order by a.F_1) C1,
count(*) over (partition by b.F_1 order by b.F_1) C2
FROM HRS.A A, HRS.B B WHERE A.F_2 = B.F_2
)x
where C1=1 and C2=1;
INNER JOIN
呢?请查看此查询。
select A_F1, B_F1 From(
SELECT a.F_1 A_F1, b.F_1 B_F1,
count(*) over (partition by a.F_1 order by a.F_1) C1,
count(*) over (partition by b.F_1 order by b.F_1) C2
FROM HRS.A A INNER JOIN HRS.B B ON A.F_2 = B.F_2
)x
where C1=1 and C2=1;
答案 1 :(得分:1)
我有答案。
在此处查看 fiddle 。
我使用了以下代码:
WITH x AS (SELECT a.f_1 AS a_f_1, b.f_1 AS b_f_1
FROM a JOIN b ON a.f_2 = b.f_2)
SELECT *
FROM x x1
WHERE NOT EXISTS (SELECT 1
FROM x x2
WHERE (x2.a_f_1 = x1.a_f_1
AND x2.b_f_1 != x1.b_f_1)
OR (x2.a_f_1 != x1.a_f_1
AND x2.b_f_1 = x1.b_f_1)
)
;
修改强>
我曾经在SQL fiddle上跟踪14毫秒内运行的代码。我删除了公用表表达式,并观察到查询性能得到了改善。
SELECT a1.f_1 AS a_f1, b1.f_1 AS b_f1
FROM a a1 JOIN b b1 ON a1.f_2 = b1.f_2
WHERE NOT EXISTS (SELECT 1
FROM a a2 JOIN b b2 ON a2.f_2 = b2.f_2
WHERE (a2.f_1 = a1.f_1
AND b2.f_1 != b1.f_1)
OR (a2.f_1 != a1.f_1
AND b2.f_1 = b1.f_1))
;
<强>输出:强>
A_F_1 B_F_1
3 1
6 2
4 4
5 7
答案 2 :(得分:1)
查询:
<强> SQLFIDDLEExample 强>
SELECT a.f_1 AS a_f_1,
b.f_1 AS b_f_1
FROM a JOIN b ON a.f_2 = b.f_2
WHERE 1 = (SELECT COUNT(*)
FROM a aa JOIN b bb ON aa.f_2 = bb.f_2
WHERE aa.f_1 = a.f_1 )
AND 1 = (SELECT COUNT(*)
FROM a aa JOIN b bb ON aa.f_2 = bb.f_2
WHERE bb.f_1 = b.f_1 )
结果:
| A_F_1 | B_F_1 |
-----------------
| 3 | 1 |
| 6 | 2 |
| 4 | 4 |
| 5 | 7 |
答案 3 :(得分:1)
根据@techdo的回答,我认为这可能更好:
select A_F1, B_F1 From(
SELECT a.F_1 A_F1, b.F_1 B_F1,a.F_2,
count(*) OVER(PARTITION BY A.F_2) C
FROM HRS.A A, HRS.B B WHERE A.F_2 = B.F_2
)x
where C=1 ;
多行的存在是由于相同的f_2。这个SQL只有一个count..over,所以你说你有大量数据,我认为这会快一点。
答案 4 :(得分:0)
这些解决方案中的每一个都需要时间,最好的一个(贾斯汀)花了将近45分钟,甚至没有返回200万条记录。我最终在临时表中插入匹配的记录,然后删除重复项,我发现它比这些数据集的解决方案要快得多。