-1

I have 3 below tables in my db

CREATE TABLE main_table
(
id   SERIAL PRIMARY KEY,
name VARCHAR(255) UNIQUE NOT NULL
);

CREATE TABLE middle_table
(
id            SERIAL PRIMARY KEY,
name          VARCHAR(255) UNIQUE NOT NULL,
main_table_id INT,
CONSTRAINT fk_main_table FOREIGN KEY (main_table_id)
    REFERENCES main_table (id)
);

CREATE TABLE sub_table
(
id              SERIAL PRIMARY KEY,
name            VARCHAR(255) UNIQUE NOT NULL,
main_table_id   INT,
middle_table_id INT,
CONSTRAINT fk_main_table FOREIGN KEY (main_table_id)
    REFERENCES main_table (id),
CONSTRAINT fk_middle_table FOREIGN KEY (middle_table_id)
    REFERENCES middle_table (id)
);

I have also inserted a sample data for convenience

INSERT INTO main_table (id, name) VALUES (1, 'Main 1');

INSERT INTO main_table (id, name) VALUES (2, 'Main 2');

INSERT INTO middle_table (id, name, main_table_id) VALUES (1, 'Middle 1', 1);

INSERT INTO sub_table (id, name, main_table_id, middle_table_id) VALUES (1, 'Sub 1', 1, 1);

INSERT INTO sub_table (id, name, main_table_id) VALUES (2, 'Sub 2', 2);

INSERT INTO sub_table (id, name, main_table_id) VALUES (3, 'Sub 3', 1);

and below is the query which I am running

SELECT mt.id,
    mt.name,
    count(DISTINCT st.id)             AS direct_st_count,
    count(DISTINCT mt_st.id)          AS via_middle_st_count
    --  count(DISTINCT mt_st.id OR st.id) AS st_count
    --  Please note I need distinct count of sub tables whether they are joined directly or via middle table
FROM main_table AS mt
    LEFT JOIN sub_table st ON mt.id = st.main_table_id
    LEFT JOIN middle_table ON mt.id = middle_table.main_table_id
    LEFT JOIN sub_table mt_st ON middle_table.id = mt_st.middle_table_id
GROUP BY mt.id;

I am unable to get distinct count of sub table(it can be joined directly or via middle table).

5
  • Your scheme is wrong. The row in sub_table may easily refer to one row in main_table directly, and on another row - via middle_table.
    – Akina
    Feb 8, 2021 at 11:05
  • you are right. its a legacy system and I am not allowed to change schemas @Akina
    – Tanweer
    Feb 8, 2021 at 11:12
  • If so then you MUST to decide what link of these two contradictable ones will be ignored.
    – Akina
    Feb 8, 2021 at 11:13
  • doesnt matter really but lets say if there is a duplicate sub table joined id for one main table we consider the one joined via middle table
    – Tanweer
    Feb 8, 2021 at 11:15
  • @Akina how can I tell count function to apply distinct on these two joined tables and ignore duplicate(AS st table) if found
    – Tanweer
    Feb 8, 2021 at 11:48

1 Answer 1

0

Check this:

SELECT mt.id main_id, mt.name main_name, st.id sub_id, st.name sub_name  
FROM main_table AS mt
LEFT JOIN sub_table st ON mt.id = st.main_table_id
WHERE st.middle_table_id IS NULL
-- AND st.main_table_id IS NOT NULL

UNION ALL

SELECT mt.id, mt.name, st.id, st.name
FROM main_table AS mt
LEFT JOIN middle_table ON mt.id = middle_table.main_table_id
LEFT JOIN sub_table st ON middle_table.id = st.middle_table_id
WHERE st.middle_table_id IS NOT NULL

ORDER BY main_name, sub_name

First subquery selects the rows joined directly and have no indirect joinings. Second selects indirect joinings.

fiddle

If you do not need in rows from main table which have no matched rows from sub table at all then uncomment the condition.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.