I have a structure of a table have many fields
| table_id | name_table | name_filed | PK | FK |
|---|---|---|---|---|
| 1 | person | id | pk | |
| 1 | person | name | ||
| 1 | person | age | ||
| 2 | dog | id | pk | |
| 2 | dog | name | ||
| 2 | dog | owner | fk | |
| 3 | phone | id | pk | |
| 3 | phone | name | ||
| 3 | phone | owner | fk |
How to get id(s) of parent tables which haven't any foreign key with another table in this case expected result is 1
I've tried
select distinct table_id from tables_structure where fk!=''
Also I've tried with group by
select table_id from tables_structure where fk!=''
group by table_id
having fk!=''
CodePudding user response:
The first issue is that you are comparing to an empty string, generally we expect the empty value to be represented by a null value, so try comparing using IS NULL
select distinct table_id from tables_structure where fk IS NULL
But that isn't likely to help you here, your data represents an UNPIVOT structure, your second attempt would work if you used a COUNT in your HAVING clause, here we don't even have to compare nulls because COUNT will exclude nulls for us!
select table_id
from tables_structure
group by table_id
having COUNT(fk) = 0
If the values really are empty strings, and not nulls, then we can still use count with nulls by treating '' as a null value using NULLIF:
select table_id
from tables_structure
group by table_id
having COUNT(NULLIF(fk,'')) = 0
We can't just filter by fk <> '' as that will modify the dataset and return ALL records.
You can use a SUM over a CASE statement that computes a 1 or 0 for each record, but now things are getting complicated:
select table_id
from tables_structure
group by table_id
having SUM(CASE fk WHEN '' THEN 0 ELSE 1)) = 0
