我正在使用PostgreSQL 8.1,我有两个数据库,其中一个表名称客户端相同,每个包含+ -50k行。
我需要在一个表中获取所有不在另一个表中的ID,我有以下解决方案
$sql = "SELECT id FROM clients WHERE id NOT IN(".pg_query($conn1,'SELECT id FROM clients').")";
$result = pg_query($conn2,$sql);
在我运行之前,这是通过PHP实现它的好方法还是其他更快捷的方法?
不幸的是我无法使用dblink,因为我没有权限安装它。
答案 0 :(得分:1)
您可以使用dblink来引用查询中其他数据库中的表。
然后您的查询看起来像这样(多种不同方法之一):
SELECT id
FROM clients c
LEFT JOIN (
SELECT *
FROM dblink('dbname=mydb', 'SELECT id FROM clients')
AS c(id int)
) x USING (id)
WHERE x.id IS NULL;
由于PostgreSQL 9.1 installing an additional module变得更加简单:
CREATE EXTENSION dblink;
每个数据库运行一次。至于the necessary privileges:
加载扩展程序需要具有相同的权限 需要创建其组件对象。对于大多数扩展这个 表示需要超级用户或数据库所有者权限。
如果dblink(或类似的x-db工具不适合您,请尝试COPY
TO / FROM来传输外表的内容:
在国外db:
COPY clients TO '/path/to/file';
在家里db:
CREATE TEMP TABLE c_tmp (LIKE clients);
COPY c_tmp FROM '/path/to/file';
SELECT id
FROM clients c
LEFT JOIN c_tmp x USING (id)
WHERE x.id IS NULL;
温度。表会在会话结束时自动删除。
答案 1 :(得分:1)
如果你不能使用数据库链接,我认为你必须在中间件中进行 - 而且这个中间件应该有很多RAM。
我还建议不要将PHP用于此目的,但如果你没有其他可能性,我会这样做:
$ids = array();
$idsNotExist = array();
$resultDb1 = pg_query('SELECT id FROM db1');
while ( $row = pg_fetch_dontknowtheexactfunction_row($resultDb1) ) {
array_push($ids, $row['id']);
}
$resultDb2 = pg_query('SELECT id FROM db2');
while ( $row = pg_fetch($resultDb2) ) {
if ( !in_array($ids, $row['id']) ) {
array_push($idsNotExist, $row['id']);
}
}
最好的办法当然是,因为ID是主键,编写一个自己的in_array函数,当它被发现时从干草堆中删除ID,因为它不会被再次搜索而下一个搜索循环会更快一点
答案 2 :(得分:0)
SELECT id
FROM db.clients
WHERE id NOT IN (
SELECT id
FROM otherdb.clients
)
一个查询。除非您用于第一个连接的用户标识对其中一个表没有访问权限,否则不需要多个数据库连接。 SQL允许完全绝对的db.table.field
类型规范以允许跨数据库查询。