So here is the output of my current query:
ID | Col1 | Col2 |
---|---|---|
871 | 1 | 1 |
646 | 1 | Null |
1223 | 8 | 1 |
1223 | 8 | 2 |
1223 | 8 | 3 |
1224 | 1 | 1 |
1224 | 1 | 2 |
What I'd like to do is only keep the rows which satisfy the following:
- Col2 is Null; or
- ID Col1 == Col2 for one of the rows with the same ID, e.g., the bottom two rows are not included because the second from the bottom Col1==Col2 and the bottommost is not included because the ID and Col1 match the second from the bottom in which Col1==Col2.
For this table, the only rows which should remain are the ones with IDs 646 and 1223.
I tried the following where
clause, however it's improperly retaining the bottommost row: (Col2 is null and Col1 is not null) or (Col1 <> Col2)
. Any help appreciated!!
CodePudding user response:
You can do this:
select *
from my_table
where (Col2 is null and Col1 is not null)
or (id not in (select id
from my_table
where Col1 = Col2)
)
db-fiddle here: https://www.db-fiddle.com/f/xmufn82r9W522YiKKh1Qka/0
CodePudding user response:
I would firstly mark the IDs and col1 of bad rows, then filter the table using these marked rows:
WITH marked AS
(
SELECT DISTINCT ID, Col1
FROM table
WHERE Col1 = Col2 OR Col1 IS NULL AND Col2 IS NULL
)
SELECT ID
FROM table t1
LEFT JOIN marked t2 ON t1.ID = t2.ID AND t1.Col1 = T2.ColId
WHERE t2.ID IS NULL
CodePudding user response:
Your logic can be applied with NOT EXISTS
:
SELECT t1.*
FROM tablename t1
WHERE t1.Col2 IS NULL
OR NOT EXISTS (
SELECT 1
FROM tablename t2
WHERE t2.Col1 = t2.Col2 AND t2.ID = t1.ID
);
See the demo.