I have a simple database schema composed of 3 tables
User
id
name
matricule
Document
id
serial
User_Document (join table)
user_id
document_id
I want to check if all items of list( list of Document.serial) exists in the join table(User_Document) then return true If at least one not exists it should return false
There is my current query
SELECT CASE WHEN EXISTS (
SELECT *
FROM user_document ud
INNER JOIN document d ON d.id= ud.document_id
INNER JOIN user u ON u.id = ud.user_id
where u.matricule='123'
and d.serial in ('#1' ,'#2' , '#3')
)
THEN TRUE
ELSE FALSE
END
This doesn't work because it will returns always true even if a single item of list doesn't exist in the join table
I am under PostgreSQL
Thank you very much
Aggregate serials in an array and compare with an array of the desired serials:
SELECT ARRAY(SELECT d.serial
FROM user_document ud
JOIN document d ON d.id = ud.document_id
JOIN "user" u ON u.id = ud.user_id
WHERE u.matricule = '123') @> ARRAY['#1', '#2', '#3']::varchar[];
Note that I had to quote the table name for user
in the query, since it's a reserved key word in PostgreSQL and the SQL standard.
Another approach is to count the distinct serials matching the list and check that the count matches the length of the list:
SELECT count(DISTINCT d.serial) = 3
FROM user_document ud
JOIN document d ON d.id= ud.document_id
JOIN "user" u ON u.id = ud.user_id
WHERE u.matricule='123' AND d.serial IN ('#1','#2','#3');
This version also works with databases that do not support arrays (such as MySQL), and might be more efficient if there is a large number of documents related to the user.