nicholaswmin
nicholaswmin

Reputation: 22989

Conditional JOINs in Class Table Inheritance in mySQL

Is there a way to do a conditional JOIN so that it returns columns of either of one of the child tables based on a parent table field?


tl;dr:

I am trying to implement Class Table Inheritance (aka Table Per Type Inheritance) in mySQL. AFAIK it's not offered out of the box so some hacking around is needed to make it tick.

Considering the following SQL schema.

Customer

What I'd like to do:


An Ideal Result Set:

Result with <code>Customer</code> & <code>CustomerIndividual</code> columns combined

Result with <code>Customer</code> & <code>CustomerOrganization</code> columns combined

It's important to note that this query will always return 1 record only, so yes the column number would be variable.


What I'm currently doing:

  SELECT *
  FROM Customer
  LEFT JOIN CustomerIndividual
  ON Customer.idCustomer = CustomerIndividual.idCustomer
  LEFT JOIN CustomerOrganization
  ON Customer.idCustomer = CustomerOrganization.idCustomer
  WHERE Customer.idCustomer = ?

but this of course:

My question:

Is there a way to do a conditional JOIN so that it returns columns of either of one of the child tables based on the Customer.typeIndividual/Customer.typeOrganization fields?

Notes:

Upvotes: 3

Views: 607

Answers (1)

Juan Carlos Oropeza
Juan Carlos Oropeza

Reputation: 48197

Maybe you can do this, but I dont recommend it.

SELECT
  Customer.*,
  COALESCE(CI.firstName, CO.organizationName) AS firstName_or_organizationName,
  COALESCE(CI.maidenName, CO.registrationNo) AS maidenNamee_or_registrationNo,
  lastName --  here you get last_name or NULL if is an organization
  FROM Customer C
  LEFT JOIN CustomerIndividual  CI
         ON Customer.idCustomer = CustomerIndividual.idCustomer
  LEFT JOIN CustomerOrganization CO
         ON Customer.idCustomer = CustomerOrganization.idCustomer
  WHERE Customer.idCustomer = ?

Or use a store procedure

DELIMITER ;;
CREATE DEFINER=CURRENT_USER PROCEDURE stored_procedure_name(IN CustomerID INT)
BEGIN
    DECLARE boolTypeIndividual INT;

    SELECT Customer.typeIndividual into boolTypeIndividual
    FROM Customer
    WHERE Customer.idCustomer = CustomerID 

    IF (boolTypeIndividual) THEN
            SELECT C.*,   CI.*
            FROM Customer C
            LEFT JOIN CustomerIndividual  CI
                   ON Customer.idCustomer = CustomerIndividual.idCustomer
            WHERE Customer.idCustomer = CustomerID 
    ELSE
            SELECT C.*,   CO.*
            FROM Customer C
            LEFT JOIN CustomerOrganization CO
                   ON Customer.idCustomer = CustomerOrganization.idCustomer
            WHERE Customer.idCustomer = CustomerID 
    END IF
END;;
DELIMITER ;

Upvotes: 2

Related Questions