I have two lookup tables
One for pickup locations
One for extras
The problem is I’m getting each locations entry in double
and each extras entry in 7x.
I know my syntax is wrong but I’m not sure how to code what I need.
This is the syntax I’m using to link get all the info
SELECT products.id
, products.title
, products.cost
, products.extra_cost
, products.extra_cost_note
, products.saving_note
, products.picture_url
, GROUP_CONCAT(pickup_locations.location SEPARATOR "\
") AS locations
, GROUP_CONCAT(extras.title SEPARATOR "\
") AS extras
, products.status
FROM products
LEFT OUTER JOIN product_pickup
ON product_pickup.product_id = products.id
LEFT OUTER JOIN pickup_locations
ON pickup_locations.id = product_pickup.pickup_id
LEFT OUTER JOIN product_extras
ON product_extras.product_id = products.id
LEFT OUTER JOIN extras
ON extras.id = product_extras.extras_id
WHERE products.status = 1 || products.status = 2
GROUP BY products.id
ORDER BY products.title
a product can have multiple pickup locations and multiple extras. So the product_pickup and product_extras are basic lookup tables with two columns (product_id & pickup_id) or (product_id & extra_id). If I remove the two last left outer joins, I get all the right pickup locations but as soon as I re-add the two last left outer joins I get repeated values.
a classic example of cross join effects produced by have two one-to-many relationships in the same query
solved by the classic technique of pushing down the grouping into subqueries
SELECT products.id
, products.title
, products.cost
, products.extra_cost
, products.extra_cost_note
, products.saving_note
, products.picture_url
, COALESCE(l.locations,'') AS locations
, COALESCE(e.extras,'') AS extras
, products.status
FROM products
LEFT OUTER
JOIN ( SELECT product_pickup.product_id
, GROUP_CONCAT(pickup_locations.location SEPARATOR "\
") AS locations
FROM product_pickup
INNER
JOIN pickup_locations
ON pickup_locations.id = product_pickup.pickup_id
GROUP
BY product_pickup.product_id ) AS l
ON l.product_id = products.id
LEFT OUTER
JOIN ( SELECT product_extras.product_id
, GROUP_CONCAT(extras.title SEPARATOR "\
") AS extras
FROM product_extras
INNER
JOIN extras
ON extras.id = product_extras.extras_id
GROUP
BY product_extras.product_id ) AS e
ON e.product_id = products.id
WHERE products.status IN ( 1 , 2 )
ORDER
BY products.title
yes, because each subquery takes care of producing a derived table that has (zero or) one row per product, so as long as you keep joining on a product by product basis, you can keep on doing that
COALESCE simply ensures a value (even though it’s a zero-length string) instead of returning a NULL which some displays or apps have trouble handling – you could default it to a literal string that says something like ‘None’ or ‘No results’ as well