SQL table joins - sql

I am trying to use SQL to get results back from my database but I cannot get the query right.
Above is the entity descriptions from my database and I want to get back the information for the price of a product, the quantity, and the parts associated with it. The ProductParts table is a link table between Product and Part.
Here is the values in the ProductParts table and the result that I want back. I have tried using a cross join but I can't seem to get it correct, I keep getting results like this (below)
I am currently using this query
SELECT
Product.Price,
Product.Quantity,
kit_name.PartID as "Kit Name",
blank_name.PartID as "Blank Name"
FROM Product
CROSS JOIN ProductParts as kit_name
CROSS JOIN ProductParts as blank_name
WHERE Product.ProductID = 3
AND Product.ProductID = kit_name.ProductID
AND Product.ProductID = blank_name.ProductID
This is the result I get back

Try this one:
SELECT
Product.Price,
Product.Quantity,
p.PartID AS PartID,
FROM Product
INNER JOIN ProductParts as pp
ON pp.ProductId=Product.ProductId
INNER JOIN Parts as p
ON p.PartId=pp.PartId
WHERE Product.ProductID = 3

A simple inner join between ProductPart, Product and Part would work:
SELECT
prod.Price,
prod.Quantity,
prod.ProductId as "Kit Name",
part.PartID as "Blank Name"
FROM ProductParts pp
JOIN Product as prod
on pp.ProductId = prod.ProductId
JOIN Parts part
on pp.PartId = part.PartId
WHERE pp.ProductID = 3

Related

Conditional statement to determine which table to Select from in Access 2013

I am trying to come up with a query to show the purchase and product information made by a member, and I was wondering if there is a way create a conditional statement to determine whether the product the member bought was from the Clothing table, Accessory table or if they bought a product from both tables. and the determining factor for which table is the ProductID in the Product table, if the user didn't but from the clothing table, the ProductID should be 0. The ProductID connects to both the Clothing and Accessory tables by their ProductTypeID, if you need any more information, let me know, thanks!
An image of the tables in Access is here
And here it is in SQL View
SELECT Member.MemberID, Member.FirstName, Member.LastName,
Purchase.PurchaseDate, LineItem.CalculatedPrice, Product.ProductType
FROM ClothingType
INNER JOIN ((AccessoryType INNER JOIN (((Member INNER JOIN Purchase
ON Member.MemberID = Purchase.MemberID)
INNER JOIN (Product INNER JOIN LineItem ON Product.ProductID = LineItem.ProductID)
ON Purchase.PurchaseID = LineItem.PurchaseID)
INNER JOIN Accessory ON Product.ProductID = Accessory.ProductTypeID)
ON AccessoryType.AccessoryTypeID = Accessory.AccessoryTypeID)
INNER JOIN Clothing ON Product.ProductID = Clothing.ProductTypeID)
ON ClothingType.ClothingTypeID = Clothing.ClothingTypeID;
you need to modify your query to use left joins. Unfortunately MS Access has its craziness about the parenthesis in the JOINS, so my query below may be erroneous. Please comment below if Access complains about errors in the JOIN clause, and I will do my best to fix it:
SELECT Member.MemberID, Member.FirstName, Member.LastName,
Purchase.PurchaseDate, LineItem.CalculatedPrice, Product.ProductType
FROM Member INNER JOIN (Purchase
INNER JOIN (Product INNER JOIN (LineItem
LEFT JOIN (Accessory LEFT JOIN (AccessoryType
LEFT JOIN (Clothing LEFT JOIN ClothingType ON
ClothingType.ClothingTypeID = Clothing.ClothingTypeID)
ON Product.ProductID = Clothing.ProductTypeID)
ON AccessoryType.AccessoryTypeID = Accessory.AccessoryTypeID)
ON Product.ProductID = Accessory.ProductTypeID)
ON Product.ProductID = LineItem.ProductID)
ON Purchase.PurchaseID = LineItem.PurchaseID)
ON Member.MemberID = Purchase.MemberID);
However, as I mentioned above, it may not work because of Access stupidity around its usage of JOINs. You may be better of to double-clicking on the last four join lines in the designer (to the right of Product) and make them all "Select all from the left table and only those that match from the right table" option (which is a LEFT JOIN in Access terms)
UPDATE: forgot to add: once you have your join working all you need to do is to use an expression for the Accessory/Clothing description like this:
Iif(IsNULL(AccessoryType.Description), ClothingType.Description, AccessoryType.Description) as Description

SQL query with three level categories

This problem has puzzled me a while and I hope there are some wiz that could help solve this problem. I have a product table with three level of categories (three tables). I'm trying to list all products that is connected to the last level(third level) of the categories. When running the query below ALL products in the product table is listed.
Here is the SQL query.
SELECT *
FROM Product
INNER JOIN Product_Category
ON Product.ProductCategoryID = Product_Category.ProductCategoryID
INNER JOIN Product_Sub_Category
ON Product_Category.ProductCategoryID = Product_Sub_Category.ProductCategoryID
INNER JOIN Product_Sub_Sub_Category
ON Product_Sub_Category.ProductSubCategoryID = Product_Sub_Sub_Category.ProductSubCategoryID
WHERE Product_Sub_Sub_Category.ProductSubSCategoryID = request.querystring
You need to join on SubCategoryId on the second level and SubSubCategoryId on the third level
SELECT *
FROM
Product
INNER JOIN Product_Category ON (Product.ProductCategoryID = Product_Category.ProductCategoryID)
INNER JOIN Product_Sub_Category ON (Product_Category.ProductSubCategoryID = Product_Sub_Category.ProductSubCategoryID)
INNER JOIN Product_Sub_Sub_Category ON (Product_Sub_Category.ProductSubSubCategoryID = Product_Sub_Sub_Category.ProductSubSubCategoryID)
WHERE
Product_Sub_Sub_Category.ProductSubSubCategoryID = (request.querystring)

Transferring data from different tables into dimension table

I am trying to fill my product dimension with data from AdventureWorks database using the following query
SELECT product.Class,
product.Color,
product.DaysToManufacture,
product.DiscontinuedDate,
product.ProductLine,
product.FinishedGoodsFlag,
product.ListPrice,
product.MakeFlag,
product.Name AS productName,
productDescription.[Description],
product.ProductNumber,
product.ReorderPoint,
product.SafetyStockLevel,
product.SellEndDate,
product.SellStartDate,
product.Size,
product.StandardCost,
product.Style,
product.[Weight],
model.Name AS model,
product.WeightUnitMeasureCode,
product.SizeUnitMeasureCode,
subcategory.Name AS subcategoryName,
category.Name AS categoryName,
photo.LargePhoto,
photo.LargePhotoFileName,
photo.ThumbNailPhoto,
photo.ThumbnailPhotoFileName
FROM AdventureWorks2008R2.Production.Product product
INNER JOIN AdventureWorks2008R2.Production.ProductModel model
ON (product.ProductModelID = model.ProductModelID)
INNER JOIN AdventureWorks2008R2.Production.ProductSubcategory subcategory
ON (subcategory.ProductSubcategoryID = product.ProductSubcategoryID)
INNER JOIN AdventureWorks2008R2.Production.ProductCategory category
ON (category.ProductCategoryID = subcategory.ProductCategoryID)
INNER JOIN AdventureWorks2008R2.Production.ProductProductPhoto productphoto
ON (productphoto.ProductID = product.ProductID)
INNER JOIN AdventureWorks2008R2.Production.ProductPhoto photo
ON (productphoto.ProductPhotoID = photo.ProductPhotoID)
INNER JOIN AdventureWorks2008R2.Production.ProductModelProductDescriptionCulture productModelDescription
ON (productModelDescription.ProductModelID = model.ProductModelID)
INNER JOIN AdventureWorks2008R2.Production.ProductDescription productDescription
ON (productModelDescription.ProductDescriptionID = productDescription.ProductDescriptionID)
WHERE productModelDescription.CultureID = 'en';
However there are 504 product records in Product tables, but this query yields only 294 records. After tracing the query for a while, I figured out that the joins to get product description is the reason for the deducted number of product records.
My question is how to get All product records (504) while getting product description information as well, if not found put NULL
You can use FULL OUTER JOIN with ProductDescription table.
.....
.....
INNER JOIN AdventureWorks2008R2.Production.ProductModelProductDescriptionCulture productModelDescription
ON (productModelDescription.ProductModelID = model.ProductModelID)
FULL OUTER JOIN AdventureWorks2008R2.Production.ProductDescription productDescription
.....
By using LEFT JOIN you will get all products. INNER JOIN will remove the once rows that do not match in your ON statement.
Edit: This image shows you the results from the different types of joins:
You can see there that by using INNER JOIN you only get the rows where both tables overlap, while using LEFT JOIN you will always return the full set of the first table.

Join in Query WHERE clause

I have several tables I"m trying to get data out of efficiently.
I have a drafted query as such:
SELECT products.id, products.name products.extended_description, products.catalogid, products.image1, products.image2, products.stock, products.price, manufacturer.manufacturer, products.weight
FROM products
JOIN manufacturer ON (products.manufacturer = manufacturer.id)
WHERE category.category_name = ?;
Obviously this is a broken query, but I'm not sure how to fix this. I need to somehow join category table to product_category table which is related to products table via the products.catalogid field.
My feeble attempt is as such:
SELECT products.id, products.name products.extended_description, products.catalogid, products.image1, products.image2, products.stock, products.price, manufacturer.manufacturer, products.weight
FROM products
JOIN manufacturer ON (products.manufacturer = manufacturer.id)
FROM category
JOIN product_category ON (category.id = (SELECT product_category.id FROM product_category WHERE product_category.catalogid /*I'm so lost...*/))
WHERE category.category_name = ?;
Basically I need to query the db for all the info in the SELECT clause where the category name is "NEW"... and I'm completely stumped (my SQL obviously needs some work!)
Something like this, just keeping joining and joining and....
SELECT
*
FROM
products as p
JOIN
manufacturer as m
ON
p.manufacturer = m.id
JOIN
product_category as pc
ON
pc.product = p.id
JOIN
category as c
ON
c.id=pc.category
WHERE
c.name = "NEW"
Since you've got a product_category table, it appears that your product may belong to multiple categories. In cases like that, you want to check if a category that you are looking for is among the categories assigned to your product.
One way of doing it is with an EXISTS condition:
SELECT p.id, p.name p.extended_description, p.catalogid, p.image1, p.image2, p.stock, p.price, m.manufacturer, p.weight
FROM products p
JOIN manufacturer m ON (p.manufacturer = m.id)
WHERE
EXISTS (
SELECT *
FROM product_category pc
JOIN category c ON c.id=pc.categoryId
WHERE pc.productId = p.id
AND c.category.category_name = ?
)
I assumed that the product_category many-to-many table has columns categoryId and productId which bring together the IDs of the product and a category to which that product belongs.

Get correct result from mysql query

I have the following tables:
**products** which has these fields: id,product,price,added_date
**products_to_categories** which has these fields: id,product_id,category_id
**adverts_to_categories** -> id,advert_id,category_id
**adverts** which has these fields: id,advert_name,added_date,location
I can not execute sql that will return to me all products that are from category 14 and that are owned by advert located in London. So I have 4 tables and 2 conditions - to be from category 14 and the owner of the product to be from London. I tried many variants to execute sql but none of the results were correct.. Do I need to use Join and which Join - left, right, full? How the correct sql will look like? thank you in advance for your help and sorry for boring you :)
This is what I have tried so far:
SELECT p.id, product, price, category_id,
p.added_date, adverts.location, adverts.id
FROM products p,
products_to_categories ptc,
adverts,
adverts_to_categories ac
WHERE ptc.category_id = "14"
AND ptc.product_id=p.id
AND ac.advert_id=adverts.id
AND adverts.location= "London"
pretty basic logic
Select * from Products P
INNER JOIN Products_To_Categories PTC ON P.ID = PTC.Product_ID
INNER JOIN Adverts_to_Categories ATC ON ATC.Category_Id = PTC.Category_ID
INNER JOIN Adverts AD on AD.ID = ATC.Advert_ID
WHERE PTC.Category_ID = 14 and AD.Location = 'LONDON'
you would only need a LEFT or right join IF you wanted records from a table which didn't exist in other tables.
so for example, if you wanted all products even if a records even those without a category, then you would use a LEFT Join instead of inner.
The following statement should return all columns from the product table in category with id 14 and all adverts located in London:
select p.* from products p
inner join products_to_categories pc on p.id = pc.product_id
inner join adverts_to_categories ac on pc.category_id = ac.category_id
inner join adverts a on a.id = ac.advert_id
where pc.category_id = 14
and ac.location = 'London';
You should remember to add an index to the column location if you are doing these string-based queries very often.