我正在使用PostgreSQL 9.6只读副本,我无法创建函数或临时表。
在一个表中,有一个应该在光盘上的文件列表。在完全不同的服务的目录中,有文件本身,由file_id命名。
Column | Type
-----------+-----------
file_id | integer
name | text
在另一台机器的光盘上
ls -rt /var/www/dbfiles
519288 519290 519297 519298 519231 ...
有大约5000条记录和大约5000个文件,但我有理由相信它们不匹配。所以我试图找到一种方法来运行一个查询,该查询将显示数据库中的哪些记录在光盘上没有文件,以及光盘上哪些文件在数据库中没有记录。现在这是一次性的,所以我不介意目录列表的一定程度的手工操作。
如果我可以将目录列表导入到表中,我只需要进行外连接并在每一侧查找空值。有没有办法可以外部加入一个充满ID的子查询?就像是
SELECT f.name, dir_listing.id FROM files f
FULL OUTER JOIN (SELECT (519288, 519290, 519297, 519298, 519231...) AS id) AS dir_listing
输出看起来像
name | id
---------------+---------
myfile.txt | 519288
otherfile.txt |
| 519290
(等等)
保存我从CSV和VLOOKUP!
你可以使用VALUES()
:
SELECT f.name, dir_listing.id
FROM files f FULL OUTER JOIN
(VALUES (519288), (519290), (519297), (519298), (519231),
) AS dir_listing (id)
ON f.file_id = dir_listing.id;
你的想法有效,你只是使用了错误的语法。
这个表达式:
SELECT (519288, 519290, 519297, 519298, 519231...)
返回一行,其中一列是一个包含大量字段的匿名记录。
您可以做的是在values子句中列出ID(从INSERT语句中可以知道):
SELECT f.name, dir_listing.id
FROM files f
FULL OUTER JOIN (
values (519288), (519290), (519297), (519298), (519231), (...)
) AS dir_listing(id) on f.id = dir_listing.id;
请注意,每个值都括在括号中,为每个值创建行。
如果你想减少一点打字,你可以使用一个unnested数组常量:
SELECT f.name, dir_listing.id
FROM files f
FULL JOIN unnest(array[519288, 519290, 519297, 519298, 519231...]) AS dir_listing(id)
on f.id = dir_listing.id;