我有两个表包含几乎相同的东西。但他们从不同来源获得数据,而在完美世界中他们是相同的。实践 - 他们不同。目标是找到匹配的记录并相互连接,然后结果是不匹配的记录。
first_table:
id1,date1,value1
second_table:
id2,date2,value2
我创建第三个表" joiner":
ID1,ID2
现在使用这个咒语:
INSERT INTO joiner (SELECT id1,id2 FROM first_table,second_table WHERE value1=value2 and date1=date2 ORDER BY date1,date2,id1,id2);
(排序很重要,因为有时候会丢失一些包,所以我必须稍后添加)
一切都会很棒,但是......有时会有不止一条记录具有相同的值和日期,并且无法识别它。接受的解决方案是首先从first_table加入第一个来自second_table,第二个来自first_table,第二个来自second_table等。
这就是问题所在。
因为joiner在每列上都有唯一键 - insert会引发unique_violation错误,因为示例结果是:
id1|id2
-------
a1| b1
a1| b2
a2| b1
a2| b2
如果我使用SELECT distinct id1,id2当然没有任何变化(a1,b1)!=(a1,b2) 如果我在(id1)id1,id2上使用SELECT distinct - 结果有时是:
id1|id2
-------
a1| b1
a2| b1
我尝试使用WHERE NOT EXISTS(SELECT 1 FROM first_table f WHERE f.id1<> first_table.id1)AND NOT EXISTS(SELECT 1 FROM second_table s WHERE s.id2<> second_table.id2) - 仍然没有
我尝试使用EXCEPTION添加函数,但这也是错误的 - 因为它引发了异常,但是joiner仍然是空的......
有什么想法吗?
更新 我不知道为什么有些人在没有任何评论的情况下投票支持我的问题。也许是因为它还不够清楚 - 特别是对于那些例子:
first_table:
id1, value1, date1
1,10, 2015-03-01
2,11, 2015-03-01
3,10, 2015-03-01
4,14, 2015-03-02
second_table:
id2, value2, date2
1,10, 2015-03-01
2,11, 2015-03-01
3,10, 2015-03-01
4,15, 2015-03-02
预期的木匠
id1, id2
1,1
2,2
3,3
正如你所看到的,id1 = 4而id2 = 4并没有木匠 - 因为价值不同(审计员需要手工检查和修复)。
并且id1 = 1和id1 = 3存在问题 - 相同,因此没有uniqness的joiner看起来像:
id1, id2
1,1
1,3
2,2
3,1
3,3
哪个错了。
答案 0 :(得分:1)
问题的解决方案是使用row_number()
枚举每个表中常见日期/值对的值。
您的查询也可以通过其他方式进行改进:
insert
时,请始终列出列。join
语法。简单规则:永远不要在from
子句中使用逗号。查询是:
INSERT INTO joiner(id1, id2)
SELECT id1, id2
FROM (select ft.*, row_number() over (partition by value1, date1 order by value1) as seqnum
from first_table ft
) ft JOIN
(select st.*, row_number() over (partition by value2, date2 order by value2) as seqnum
from second_table st
) st
ON ft.value1 = st.value2 and ft.date1 = st.date2 and ft.seqnum = st.seqnum
ORDER BY ft.date1, st.date2, ft.id1, st.id2;
我不认为order by
很重要,但是因为您认为它是相关的,所以我将其留下来。