this is my first post. I know that this is horribly inefficient and repetitive code that won't actually work, what I need to do is combine all these outputs into 1 select statement. I am obviously fairly new at this, but I've been at it all day and I just can't get started in the right direction, each snippet works on its own...please help!
Essentially I'm working with a DB with many tables, and to get the right data for each column, I often have to account for 3 tables with joins.
Thanks for any insight or help!
SELECT
Product.ProductID,
(
SELECT Abbreviation AS Country
FROM Product
LEFT JOIN ProductCountry
ON Product.ProductID = ProductCountry.ProductID
LEFT JOIN Location
ON ProductCountry.LocationID = Location.LocationID
GROUP BY Product.ProductID
),
(
SELECT r.ResourceName AS Manufacturer, rr.ResourceName AS Brand
FROM Product p
LEFT JOIN Resource r
ON p.ManufactureCode = r.ResourceID
INNER JOIN Resource rr
ON p.BrandCode = rr.ResourceID
),
Product.Name,
Product.UPC,
Product.Size,
(
SELECT Unit.abbreviation AS Measure
FROM Product
LEFT JOIN Unit
ON Product.Unit = Unit.UnitID
),
(
SELECT Category.ParentID AS Category, Category.Description AS Sub_Category
FROM Product
LEFT JOIN ProductCategory
ON Product.ProductID = ProductCategory.ProductID
LEFT JOIN Category
ON ProductCategory.CategoryID = Category.CategoryID
),
(
SELECT i.Description AS INGREDIENTS, i.MayContain AS Allergen_Statement
FROM Product
LEFT JOIN Ingredient i
ON Product.ProductID = i.IngredientID
),
(
SELECT GROUP_CONCAT( Special.Description SEPARATOR ', ' ) AS Free_From
FROM Product
LEFT JOIN ProductSpecial
ON Product.ProductID = ProductSpecial.ProductID
LEFT JOIN Special
ON ProductSpecial.SpecialID = Special.SpecialID
GROUP BY Product.ProductID
)
FROM Product, ProductStatus
WHERE ProductStatus.ProductStatusID = 1
First, some notes and assumptions...
I'm assuming the Country
column is in the Location
table, otherwise why would you bother joining it.
If you have trouble with this part, change the second join to a LEFT JOIN
. I've had occasional trouble doing left join a to b
followed by inner join b to c
. I've found it's easier to keep the LEFT JOIN
going, so my example left-joins both tables:
LEFT JOIN Resource r
ON p.ManufactureCode = r.ResourceID
INNER JOIN Resource rr
ON p.BrandCode = rr.ResourceID
You're joining to Resource
in two different ways. That's completely OK with MySQL (and all the mainstream databases). You just have to alias one or both of the joins. I've aliased one of them:
LEFT JOIN Resource ON Product.ManufactureCode ...
LEFT JOIN Resource BrandResource ON Product.BrandCode...
I don't know from your example how ProductStatus
is joined. You'll have to supply that.
Start small using the example below. Join in the Country
, then when you've got that working, join in Manufacturer
, then Brand
, then Measure
, etc. The query isn't doing a lot of advanced stuff; it's complicated mostly due to the sheer number of tables. Tackle them one at a time and you'll win :)
Finally, as @Bohemian noted in the comments, the GROUP BY
can't be brought up to the top. Actually, it probably can, but it will complicate things beyond belief. I've left that as a subquery.
Here's the final result. Note that it's not tested because it's huge and I don't have table structures or sample data. But mostly because it's huge :) At any rate, this is meant as an example only.
SELECT
Product.ProductID,
Location.Country,
Resource.ResourceName AS Manufacturer,
BrandResource.ResourceName AS Brand,
Product.Name,
Product.UPC,
Product.Size,
Unit.Abbreviation AS Measure,
Category.ParentID AS Category,
Category.Description AS Sub_Category,
Ingredient.Description AS Ingredients,
Ingredient.MayContain AS Allergen_Statement,
(SELECT GROUP_CONCAT( Special.Description SEPARATOR ', ' ) AS Free_From
FROM Product
LEFT JOIN ProductSpecial
ON Product.ProductID = ProductSpecial.ProductID
LEFT JOIN Special
ON ProductSpecial.SpecialID = Special.SpecialID
GROUP BY Product.ProductID
)
FROM Product
INNER JOIN ProductStatus ON ... however it's joined
LEFT JOIN ProductCountry ON Product.ProductID = ProductCountry.ProductID
LEFT JOIN Location ON ProductCountry.LocationID = Location.LocationID
LEFT JOIN Resource ON Product.ManufactureCode = Resource.ResourceID
LEFT JOIN Resource BrandResource ON Product.BrandCode = BrandResource.ResourceID
LEFT JOIN Unit ON Product.Unit = Unit.UnitID
LEFT JOIN ProductCategory ON Product.ProductID = ProductCategory.ProductID
LEFT JOIN Category ON ProductCategory.CategoryID = Category.CategoryID
LEFT JOIN Ingredient ON Product.ProductID = i.IngredientID
WHERE ProductStatus.ProductStatusID = 1