Postgresql 如何在postgres中“连接”两个表
我有两张桌子,里面有几乎一样的东西。但他们从不同的来源获得数据,在完美世界中,他们是相同的。实际上,它们是不同的。目标是找到匹配的记录并相互连接,然后将ummatched记录作为结果 第一张表格:Postgresql 如何在postgres中“连接”两个表,postgresql,distinct,Postgresql,Distinct,我有两张桌子,里面有几乎一样的东西。但他们从不同的来源获得数据,在完美世界中,他们是相同的。实际上,它们是不同的。目标是找到匹配的记录并相互连接,然后将ummatched记录作为结果 第一张表格: id1, value1, date1 1,10, 2015-03-01 2,11, 2015-03-01 3,10, 2015-03-01 4,14, 2015-03-02 id1,日期1,值1 第二张表格: id2, value2, date2 1,10, 2015-03-01 2,11, 2
id1, value1, date1
1,10, 2015-03-01
2,11, 2015-03-01
3,10, 2015-03-01
4,14, 2015-03-02
id1,日期1,值1
第二张表格:
id2, value2, date2
1,10, 2015-03-01
2,11, 2015-03-01
3,10, 2015-03-01
4,15, 2015-03-02
id2,日期2,值2
我创建了第三个表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);
排序很重要,因为有时会丢失一些包,所以我必须在以后添加它
一切都会很好,但是。。。有时有多条记录具有相同的值和日期,无法识别。公认的解决方案是将第一个从第一个从第二个从第一个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二个从第二
问题来了
因为joiner在每一列上都有唯一的键,所以insert会引发unique_违例错误,因为示例结果是:
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从第一个_表f中选择1,其中f.id1first_table.id1和NOT EXISTS从第二个_表s中选择1,其中s.id2second_table.id2-仍然为空
我试图添加带有异常的函数,但这也是错误的-因为它会引发异常,但joiner仍然是空的
有什么想法吗
更新
我不知道为什么有些人对我的问题不加评论就投了反对票。可能是因为它不够清晰-尤其是对于那些例子:
第一张表格:
id1, value1, date1
1,10, 2015-03-01
2,11, 2015-03-01
3,10, 2015-03-01
4,14, 2015-03-02
第二张表格:
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有一个问题-它们是相同的,所以没有统一性的joiner看起来像:
id1, id2
1,1
1,3
2,2
3,1
3,3
这是错误的。解决问题的方法是使用行编号来枚举每个表中常用日期/值对的值 您还可以通过其他方式改进查询: 使用insert时,始终列出列。 学习使用正确的显式连接语法。简单规则:不要在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不重要,但我将其保留,因为您认为它是相关的。实际上,插入中的排序并不重要。它只对插入的值有效,因为表只是行的集合,所以顺序并不重要。除非您省略了一些parts.IIUC,否则您的目标是joiner表将包含来自第一个表和第二个表的所有唯一行?也就是说:那些只出现在一个+只出现在两个+同时出现在两个顺序是选择,而不是插入。这很重要-因为id为10的项目应该在项目11之前,而没有顺序,插入的顺序是未定义的。没有理由为两者添加唯一性-如果id1是唯一的,id2是唯一的,id1+id2将始终是唯一的。至少对我来说,你的目标仍然不明确。也许你可以在问题中添加一些样本数据和你的预期结果?O!我不知道加入。。。ON可以与多个条件一起使用-您完全正确-我总是使用aaa JOIN bbb而不是aaa,bbb,但在这种情况下,我必须使用多个条件value=value,date=dateRunned,看起来还可以-没有唯一的冲突,行数非常好-现在我必须检查它是否真的需要我想要的