Search code examples
sqlms-accessself-join

Select parents that have no children in a self-join relationship


I have a simple table of category names that relates to itself with a category_parent = id. I need to select records that have no children.

From other answers I have cobbled together this statement:

SELECT cat.category_name AS 'Child Name', cat.id AS 'Child ID',
cat.category_parent AS 'Childs Parent', cat_par.category_name AS 'Parent Name', 
cat_par.id AS 'Parent ID'
FROM category AS cat
LEFT JOIN category AS cat_par ON cat.category_parent = cat_par.id
WHERE cat_par.id IS NULL;

This will successfully select records that have no PARENT. I tried changing the last clause to WHERE cat.category_parent IS NULL but that yielded an empty yet.

I have also tried this statement based on another answer:

SELECT cat.category_name AS 'Child Name', cat.id AS 'Child ID', 
cat.category_parent AS 'Childs Parent' cat_par.category_name AS 'Parent Name', 
cat_par.id AS 'Parent ID'
FROM category AS cat
WHERE NOT EXISTS 
(SELECT id FROM category AS cat_par WHERE cat.category_parent = cat_par.id);

Which returns the error No value given for one or more required parameters.


Solution

  • If you just need the id and the category name of records with no children this also works:

    SELECT
      category.id,
      category.category_name
    FROM
      category LEFT JOIN category AS category_1
        ON category.id = category_1.category_parent
    WHERE
      category_1.category_parent IS NULL
    

    and i think this query looks nice. But if you also need the parent's name, you can use this:

    SELECT
      category.id,
      category.category_name,
      category_1.category_name
    FROM
      (category LEFT JOIN category AS category_2
        ON category.id = category_2.category_parent)
      LEFT JOIN category AS category_1
        ON category.category_parent = category_1.ID
    WHERE
      category_2.category_parent Is Null;
    

    and yes, it gets a little more complicated: it's just a nice sql exercise but i would prefer to use the Exists version instead.