Domanda

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
È stato utile?

Soluzione

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top