Найти записи PostgreSQL с отсутствующими файлами на диске и файлы на диске с отсутствующими записями БД - PullRequest
0 голосов
/ 19 февраля 2019

Я работаю с репликой только для чтения PostgreSQL 9.6, в которой я не могу создавать функции или временные таблицы.

В одной таблице есть список файлов, которые должны быть на диске.А в каталоге на совершенно другом сервисе есть сами файлы с именем file_id.

  Column   |   Type
-----------+-----------
 file_id   |  integer
 name      |  text

И на диске на другой машине

ls -rt /var/www/dbfiles
519288     519290     519297     519298     519231     ...

Там около 5000 записей и около5000 файлов, но у меня есть основания полагать, что они не совпадают.Поэтому я пытаюсь найти способ выполнить запрос, который покажет, какие записи в БД не имеют файла на диске, а какие файлы на диске не имеют записи в БД.Пока это единовременно, так что я не возражаю против ручной обработки списка каталогов.

Если бы я мог импортировать список каталогов в таблицу, я бы просто сделал внешнее соединение и посмотрелдля нулей с каждой стороны.Есть ли способ, которым я могу внешнее объединение с подзапросом, полным идентификаторов?Что-то вроде

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!

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Ваша идея работает, вы просто используете неправильный синтаксис.

Это выражение:

SELECT (519288, 519290, 519297, 519298, 519231...)

возвращает одну строку с одним столбцом, которая является анонимной записью с большим количествомполя.

Что вы можете сделать, это перечислить идентификаторы в предложении значений (как известно из оператора 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;

Обратите внимание, что каждое значение заключено в скобки, создавая строку длякаждое значение.

Если вы хотите набрать немного меньше текста, вы можете использовать константу массива, которая не имеет значения:

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;
0 голосов
/ 19 февраля 2019

Вы можете использовать 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...