Skip to content
Advertisement

Exclude based on sub-table’s value

Consider the table Audit, and AuditStatus. Where auditId in AuditStatus is a foreign key, mapping the pk of table Audit.

table Audit
id    | auditName   |
1     | test        |
2     | fooTest     |
3     | barTest     |

table AuditStatus
id  | auditId | status    | 
11  | 1       | started   |
12  | 1       | completed |
13  | 2       | started   |

How can I only select the entries of table Audit, which do not have a AuditStatus.status ‘completed’.

The result in this case would be:

2     | fooTest     |   
3     | barTest     | 

I have updated the question and the result example, to make it more clear. The relation Audit -> AuditStatus is a one to many. And I want to exclude the Audits which have a refrerence to an AuditStatus with status ‘complete’

Advertisement

Answer

You should post your attempted query into your question, not as comment. Anyway, your query is actually correct but your condition is incorrect. Let’s inspect your query:

SELECT * 
  FROM Audit a 
  WHERE NOT EXISTS (
      SELECT s.auditId
        FROM AuditStatus s
       WHERE a.id = s.auditId AND s.status != 'completed'
);

You’re suppose to find where the status is not complete, which is true in the subquery but the problem here is you’re doing a NOT EXISTS which negates the correct result you’re getting from the subquery.

This is what your subquery will return:

id auditId status
11 1 started
13 2 started

Then when your NOT EXIST negates the auditId being returned, you’ll get this result instead:

id auditName
3 barTest

Which is correct according to the condition; auditId=3 wasn’t returned in the subquery. What you need to modify is actually very simple, you just need to make the subquery return status = completed as true then NOT EXISTS will return any Audit.Id that doesn’t match with the correlated subquery. Therefore:

SELECT * 
  FROM Audit a 
  WHERE NOT EXISTS (
      SELECT s.auditId
        FROM AuditStatus s
       WHERE a.id = s.auditId AND s.status = 'completed'
);

And that’s it, you should be getting the result you looking for.

Demo fiddle

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement