查找光盘上缺少文件的PostgreSQL记录,以及缺少DB记录的光盘上的文件

问题描述 投票:0回答:2

我正在使用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!

sql postgresql postgresql-9.6
2个回答
1
投票

你可以使用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;

1
投票

你的想法有效,你只是使用了错误的语法。

这个表达式:

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;
© www.soinside.com 2019 - 2024. All rights reserved.