Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to join these tables for a full result set from all tables?

I have table A of Entities

I have table B of Items

I have Table C of Entity-Items, and their associated configured values.

I'm looking to write a view that will return me a row with each combination of Entity + Item, and to use the data from table C if it exists.

In addition, if there is items in TableC that do not existing in TableB, I would like those as well

For example,

Table A 
Entity 1
Entity 2

Table B
Item X
Item Y
Item Z

Table C
Entity 1    Item X    True
Entity 1    Item Y    False
Entity 2    Item X    False
Entity 2    Item J    False


Result Table Wanted
Entity 1    Item X    True
Entity 1    Item Y    False
Entity 1    Item Z    Null
Entity 2    Item X    False
Entity 2    Item Y    Null
Entity 2    Item Z    Null
Entity 2    Item J    False

For some reason I am drawing a blank for this. It's been a while since I worked with SQL, so perhaps I'm missing something obvious. Can someone help me with identifying the syntax I need to write this query?

I've come close using CROSS JOIN

SELECT *
FROM Entities
CROSS JOIN Items
LEFT OUTER JOIN EntityItems 
    ON Entities.ID = EntityItems.EntityID
    AND Items.ID = EntityItems.ItemID

This returns me everything but the row in Table C for Item J.

Update : Scratch that, it actually returns me too many rows. That's what I'm playing with now though.

I'm using MS Sql Server 2017

like image 307
Rachel Avatar asked Feb 01 '26 13:02

Rachel


1 Answers

Your cross join/left join is the right approach:

SELECT e.EntityID, i.ItemId, COALESCE(ei.value, 'false') as value
FROM Entities e CROSS JOIN
     Items i LEFT JOIN
     EntityItems ei
    ON e.ID = ei.EntityID AND
       i.ID = ei.ItemID;

However, this assumes that ItemId is correctly defined with a foreign key relationship. You seem to have invalid ItemIds. You can fix this:

SELECT e.EntityID, i.ItemId, COALESCE(ei.value, 'false') as value
FROM Entities e CROSS JOIN
     (SELECT i.ItemId
      FROM Items i
      UNION  -- on purpose to remove duplicates
      SELECT ei.ItemId
      FROM EntityItems ei
     ) i LEFT JOIN
     EntityItems ei
    ON e.ID = ei.EntityID AND
       i.ID = ei.ItemID;

However, I strongly recommend that you fix your data (i.e. add J to the items table) and add:

alter table entityitems add constraint fk_entityitems_entityid
    foreign key (entityid) references entities(entityid);

alter table entityitems add constraint fk_entityitems_itemid
    foreign key (itemid) references entities(itemid);

This will help you ensure data integrity (moving forward) -- after you have fixed the data.

EDIT:

Ahh, you don't want the additional item ids on all the entities. If so:

SELECT e.EntityID, i.ItemId, COALESCE(ei.value, 'false') as value
FROM Entities e CROSS JOIN
     Items i LEFT JOIN
     EntityItems ei
    ON e.ID = ei.EntityID AND
       i.ID = ei.ItemID;
UNION ALL
SELECT ei.EntityId, ei.ItemId, ei.value
FROM EntityItems ei
WHERE NOT EXISTS (SELECT 1 FROM Items i WHERE i.ItemId = ei.ItemId);
like image 188
Gordon Linoff Avatar answered Feb 04 '26 05:02

Gordon Linoff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!