Нахождение недостающего подмножества в наборе - PullRequest
0 голосов
/ 17 октября 2019

У меня есть 3 таблицы:

cert         sct           server
========    =========    ============
cert_id     cert_id        serv_id
pem         serv_id        url
date_added  load           
type

По сути, каждый раз, когда я получаю новый сертификат (таблица cert), я буду отправлять его на разные серверы (в таблице server для отметки времени, исохраните ответ в таблице sct. По некоторым причинам у меня могут быть некоторые сертификаты, которые не были отправлены.

Кроме того, могут быть отправлены только сертификаты типа sign. Поэтому мне нужно повторно отправить их.

Для этого мне нужно найти сертификаты, которые не были отправлены на определенные серверы.

cert
======
cert_id       pem      date_added      type
--------------------------------------------
idCert1      (data)      (date)        sign
idCert2      (data)      (date)        email
idCert3      (data)      (date)        sign
idCert4      (data)      (date)        sign
idCert5      (data)      (date)        email


sct
====
cert_id        serv_id         load
------------------------------------
idCert1        serv1           (data)
idCert1        serv2           (data)
idCert3        serv1           (data)

server
======
serv_id       url
--------------------
serv1         url1
serv2         url2

Предполагая эти записи, я хочу получить следующие результаты:

cert_id     pem      serv_id         url
-----------------------------------------
idCert3     (data)   serv2           URL2
idCert4     (data)   serv1           URL1
idCert4     (data)   serv2           URL2

ИтакНа данный момент лучшее, что я мог сделать:

SELECT * 
FROM cert 
WHERE type='sign' 
AND cert_id NOT IN (SELECT cert_id 
                    FROM sct 
                    GROUP BY cert_id 
                    HAVING COUNT(cert_id)>=nbr_srv );

, где nbr_srv - общее количество серверов в таблице server. Этот запрос дает только те сертификаты, которые не были отправлены на все серверы. Я не знаю, возможно ли получить то, что я хочу, одним запросом.

1 Ответ

0 голосов
/ 17 октября 2019

demo: db <> fiddle

Генерация CROSS JOIN для всех возможных комбинаций сервер / сертификат и удаление реальных существующих комбинаций:

SELECT
    *
FROM
    cert c
CROSS JOIN serv s
WHERE c.type = 'sign' AND (c.id, s.id) NOT IN (
    SELECT
        cert_id, serv_id
    FROM
        sct sc
)
...