I have a table that has (among other things) a “serial number” (VARCHAR(50)) column and an “active” (BOOLEAN) column… so a sample of data might look like this:
serial | active -------------+------- ABCD232010E5 | True ABCD1820102C | False ABCD1820102C | True ZYXW06210F20 | True ABCD402004EZ | False
Now, from an outside source, I am given a list of serial numbers, like so:
ABCD232010E5 ZYXW49201X20 ABCD1820102C ABCD402004EZ ZYXW012100R3 ABCD44200B1W
Is there a single (ideally) query or series of queries I can run to get the following details:
- Does the serial number have an
active=True
entry? - If not, does it have an
active=False
entry? - If it doesn’t exist at all in the table, explicitly list it as such
I’m not terribly picky about the output, as long as:
- All the serials from my input are listed, whether or not they exist
- Each serial from my input is only listed once regardless of how many times it occurs in the table
- If it exists in the table, does at least one of the entries have
active=True
?
Something like the following would be fine (with comments added to explain why I expect the given output):
serial | exists | active -------------+--------+------- ABCD232010E5 | True | True --has one record with active=True ZYXW49201X20 | False | False --serial not found in table ABCD1820102C | True | True --has one record with active=True and 1+ with active=False ABCD402004EZ | True | False --only has record(s) with active=False ZYXW012100R3 | False | False --serial not found in table ABCD44200B1W | False | False --serial not found in table
I’d also be fine if the output were just two columns, with active=<null> for serial numbers that didn’t exist in the table. As I said I’m not picky, I just need to be able to distinguish the three states (exists and has active=True, exists and doesn’t have active=True, doesn’t exist).
Advertisement
Answer
One method is subqueries:
select i.*, (exists (select 1 from serials s where s.serial = i.serial and active )) as has_active_true, (exists (select 1 from serials s where s.serial = i.serial and not_active )) as has_active_false, (not exists (select 1 from serials s where s.serial = i.serial )) as no_match from input i;
This can be run directly against a list of values by replacing input i
at the end with the following:
(VALUES ('serial1'),('serial2'),('serial3'), ('serial4'),('serial5'),('serial6') ) AS i (serial)