HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

Struggling with left join - products

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
leftwithjoinstrugglingproducts

Problem

I got a quite easy question for you.

I have a table

products [ID,Name,Category,Price]


and a table

product_client[ID,product_ID,client_ID]


The products table contains all the products of course, but what the product_client does is, it is storing some products that are exclusively for a certain client.

So I wrote a small query for this one

SELECT * 
FROM product
LEFT JOIN product_client ON product.ID = product_client.product_id
WHERE product_client.client_id =1


Everything works fine, returns me the products exclusively for this client. But what I want is more - the products table is like a dictionary where on top of that client has his own products. So I need to get the whole products table, plus the query output above.

Any tips? Is it a good idea to have this set up this way?

Consider a case where:

  • In the database we have ids 1.2.3.4.5



  • Product ids 1.2 are assigned to client 1



  • The product ids 3.5 are assigned to client 2.



We want to query for client 1. So we expect to get the following ids: 1.2.5, since 3 belong to clients 2, and number 4 is a global product (unassigned). Any unassigned is a global product.

Products Table

+-----+-------------+-----------+-------+
| ID | Name | Category | Price |
+-----+-------------+-----------+-------+
| 1 | Paper | Material | 10 |
| 2 | Wool | Material | 4 |
| 3 | Cleaning | Service | 10 |
| 4 | Something | Service | 1 |
| 5 | Something2 | Service | 2 |
+-----+-------------+-----------+-------+


Client Table

+-----+---------+-------------------+
| ID | Name | {anyextra fields} |
+-----+---------+-------------------+
| 1 | Client1 | |
| 2 | Client2 | |
+-----+---------+-------------------+


product_client Table

`+-----+-----------------+-----------+
| ID | product_client | client_ID |
+-----+-----------------+-----------+
| 1 | 1 | 1 |
| 2 |

Solution

Your "where" clause restricts it to products where it is matching the client products (As you may know, left join returns everything from the left side, with matching entries from the right side or NULL otherwise. But then you filter it for a specific client value) - I would amend your WHERE clause to:

WHERE 
    product_client.client_id = 1 
    OR product_client.client_id IS NULL


My logic is - you are matching either the specific client, or the values that are "unmatched" to another (e.g. client_id = 2) client. client_id is null where the product doesn't match a specific client.

To determine which one is a global product and which one is a client's only, add to the select statement:

CASE 
    WHEN product_client.client_id IS NULL 
        THEN 'Global' 
    ELSE 'Client' 
END


For MySQL/PHP add ( ) around the statement.

You could also ISNULL(client_id,"Global") if wanting to take the specific client if it's specified, or otherwise 'global'.

Code Snippets

WHERE 
    product_client.client_id = 1 
    OR product_client.client_id IS NULL
CASE 
    WHEN product_client.client_id IS NULL 
        THEN 'Global' 
    ELSE 'Client' 
END

Context

StackExchange Database Administrators Q#132524, answer score: 6

Revisions (0)

No revisions yet.