Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joining two tables using third as linking table, including null entries

I've looked at a number of similar questions, but have yet to stumble upon/find the correct solution to the problem below.

Given the following three tables:

account
    profile_id number (nullable)
    bill_acct varchar
    status varchar (nullable)
    remarks varchar (nullable)


stage
    ecpd_profile_id number (nullable)
    bill_account varchar (nullable)
    account_class varchar (nullable)

profile
    ecpd_profile_id number
    reg_prof_id number

I need to create a join(s) to select the following:

account.bill_act, account.status, account.remarks, stage.account_class

where

profile.ecpd_profile_id = (given number)

account.profile_id and profile.reg_prof_id are equivalent

stage.ecpd_profile_id and profile.ecpd_profile_id are equivalent

stage.bill_acct and account.bill_acct are equivalent

I've tried the following...

select
    account.bill_acct,
    account.status,
    account.remarks,
    stage.account_class
from
    registration_account account
        join registration_profile profile
            on account.profile_id = profile.reg_prof_id
        join acct_stg stage
            on stage.ecpd_profile_id = profile.ecpd_profile_id
                and stage.bill_acct = account.bill_acct
where
    profile.ecpd_profile_id = ?

This works, but excludes all of the account entries for which there is no match in stage.

I need to have all rows of account.bill_acct=stage.bill_acct, appending an additional column for the stage.account_class where it exists, or null otherwise.

Multiple joins always throw me.

Thoughts?

like image 891
David Nedrow Avatar asked Sep 08 '12 15:09

David Nedrow


People also ask

How do I join two tables with NULL values in SQL?

Since it's not possible to join on NULL values in SQL Server like you might expect, we need to be creative to achieve the results we want. One option is to make our AccountType column NOT NULL and set some other default value. Another option is to create a new column that will act as a surrogate key to join on instead.

How do you join a table with NULL values?

The result of a join of null with any other value is null. Because null values represent unknown or inapplicable values, Transact-SQL has no basis to match one unknown value to another. You can detect the presence of null values in a column from one of the tables being joined only by using an outer join.

Can we apply joins on 2 tables which has no related data?

Yes, you can! The longer answer is yes, there are a few ways to combine two tables without a common column, including CROSS JOIN (Cartesian product) and UNION. The latter is technically not a join but can be handy for merging tables in SQL.

Can you join 3 tables together?

It is possible to use multiple join statements together to join more than one table at the same time. To do that you add a second INNER JOIN statement and a second ON statement to indicate the third table and the second relationship.


2 Answers

Try left join:

select
    account.bill_acct,
    account.status,
    account.remarks,
    stage.account_class
from
    registration_account account
    left join registration_profile profile
            on account.profile_id = profile.reg_prof_id
    left join acct_stg stage
            on stage.ecpd_profile_id = profile.ecpd_profile_id
                and stage.bill_acct = account.bill_acct
where
    profile.ecpd_profile_id = ?
like image 59
Robert Avatar answered Sep 22 '22 09:09

Robert


As you want to extract all the information independent on stage table(no matches on stage table), the best suitable to use LEFT JOIN in following way:

SELECT
    account.bill_acct,
    account.status,
    account.remarks,
    stage.account_class
FROM
    registration_account account
        JOIN registration_profile profile
            ON account.profile_id = profile.reg_prof_id
       LEFT JOIN acct_stg stage
            ON stage.ecpd_profile_id = profile.ecpd_profile_id
                and stage.bill_acct = account.bill_acct
WHERE
    profile.ecpd_profile_id = ?

LEFT JOIN returns all records from the left table or all record before LEFT JOIN, even if there are no matches in the right table.

like image 39
Akash KC Avatar answered Sep 24 '22 09:09

Akash KC