I have several tables: models, products, specs, pictures and stores.
They are associated as follows:
Each product belongs to (model, store)
Each picture belongs to (product)
Each spec belongs to (product)
I need a list of products,
with the store they belongs to (by product.store_id)
where product.model_id=some_id
ONLY if there are specs for the product (by spec.product_id)
ONLY if a product has pictures (by picture.product_id)
What type of query do I need?
thanks
Your definition is very complete and can be translated quite literally:
select
-- Selecting all fields of product and store.
-- You can refine this by only listing the fields you need.
p.*,
s.*
from
-- need a list of products,
product p
-- with the store they belongs to (by product.store_id)
inner join store s on s.store_id = p.store_id
where
-- ONLY if there are specs for the product (by spec.product_id)
exists
(select
'x'
from
spec ps
where
ps.product_id = p.product_id) and
-- ONLY if a product has pictures (by picture.product_id)
exists
(select
'x'
from
pictures pp
where
pp.product_id = p.product_id)
Try this::
Select * from
from
product p
inner join model m on (p.model_id=m.id)
inner join store s on (p.store_id=s.id)
inner join picture pc on (p.picture_id=pc.id)
inner join spec sp on (p.spec_id=sp_id)
where product.model_id=some_id
GROUP BY product.id
Related
I have 5 tables that need to be joined. These tables have to do with orders placed by customers and the orders turned into purchase orders for the relevant suppliers.
Table product_sale holds the customers products that they've ordered.
Table product holds the main information on those products.
Table sale_purchase is a bridging table between the sale and purchase order.
Note: This may or may not exist as the product might be out of stock and no purchase order was required.
Table product_purchase holds those linked products on the purchase order.
Table grn handles the receiving of those products.
Unfortunately in the customers sales order, I will need to access information from all of these tables. Here's the query I have so far:
SELECT
ps.*,
pp.received_qty,
p.group_ref,
p.subgroup_ref,
g.grn_id AS 'grn_ref',
g.grn_date
FROM
product_sale ps
INNER JOIN product p ON ps.product_ref = p.product_id
LEFT JOIN sale_purchase sp ON ps.sale_ref = sp.sale_ref
LEFT JOIN product_purchase pp ON pp.so_line_no = ps.line_no
LEFT JOIN grn g ON g.grn_id = pp.grn_ref
WHERE
ps.sale_ref = 150002
GROUP BY
line_no
ORDER BY
line_no
So far so good, although the received_qty for one line is wrong:
The first line's received qty should be 7 and not 4. I've checked the grn table and it definitely says 7. Can I please get some help as to where I am going wrong with this query? Also the grn_ref and grn_date should be NULL for line_no 1.00
Scrap it guys. I figured it out. I hadn't accounted for another purchase order that was in the system. Solution to the problem was adding AND pp.purchase_ref = sp.purchase_ref to the left join for product_purchase. See revised code below:
SELECT
ps.*,
pp.received_qty,
p.group_ref,
p.subgroup_ref,
g.grn_id AS 'grn_ref',
g.grn_date
FROM
product_sale ps
INNER JOIN product p ON ps.product_ref = p.product_id
LEFT JOIN sale_purchase sp ON ps.sale_ref = sp.sale_ref
LEFT JOIN product_purchase pp ON pp.so_line_no = ps.line_no AND pp.purchase_ref = sp.purchase_ref
LEFT JOIN grn g ON g.grn_id = pp.grn_ref
WHERE
ps.sale_ref = 150002
GROUP BY
line_no
ORDER BY
line_no
Running the following SELECT query gives unexpectedly two times the same record while there is only 1 product in the database. The are however multiple subcategories linked to the same category, but I still don't understand why this would give two results.
The ERD:
The full contents of the DB:
SELECT p.id AS productId, p.name AS productName FROM product p
INNER JOIN product_base AS pb ON pb.id = p.product_base_id
INNER JOIN product_category AS pc ON pc.id = pb.product_category_id
INNER JOIN product_subcategory AS psc ON psc.product_category_id = pc.id;
Returns:
Why is this product returned two times?
Appending WHERE psc.id = 2 will still give one product as a result, while the intention is that this product should only be found when psc.id = 1.
What am I missing here? Is there something wrong with the structure? How would I get all products that have a certain subcategory?
Would I need to store product_category_id and product_subcategory_id directly in product as well?
#barmar made me realize I am simply missing a direct FK from product to product_subcategory. Otherwise there is of course a missing link between the product and subcategory.
DISTINCT will filter out the duplicates.
SELECT DISTINCT p.id AS productId, p.name AS productName
FROM product p
INNER JOIN product_base AS pb ON pb.id = p.product_base_id
INNER JOIN product_category AS pc ON pc.id = pb.product_category_id
INNER JOIN product_subcategory AS psc ON psc.product_category_id = pc.id;
I am new to MySQL, trying to understand how join works.
I have two tables: categories and products each with id and name fields.
Third table is product_to_category (many to many) with category_id and product_id.
I wanted to list all categories containing specified product (with id = 5).
To do this, I made a following query:
SELECT `categories`.`id`, `categories`.`name`
FROM `categories`
LEFT JOIN `product_to_category`
ON `categories`.`id` = `product_to_category`.`category_id`
WHERE `product_to_category`.`product_id` = 5
I am wondering if it is possible to something opposite: to list all categories which does not contains specified product?
Many thanks!
I'd use the not exists operator for this:
SELECT c.`id`, c.`name`
FROM `categories` c
WHERE NOT EXISTS (SELECT *
FROM `product_to_category` ptc
WHERE c.`id` = ptc.`category_id` AND
ptc.`product_id` = 5)
SQL newbie here.
So we have 3 tables:
categories(cat_id,name);
products(prod_id,name);
relationships(prod_id,cat_id);
It is a one-to-many relationship.
So, given a category name say "Books". How do I find all the products that come under books?
As an example,
categories(1,Books);
categories(2,Phones);
products(302,Sherlock Holmes);
relationships(302,1);
You need to JOIN the three tables.
SELECT p.*
FROM relationships r
INNER JOIN products p
ON p.prod_id = r.prod_id
INNER JOIN categories c
ON c.cat_d = r.cat_id
WHERE c.name = 'Books'
You have to join tables on related columns and specify WHERE clause to select all records where category name = 'Books'
SELECT p.*
FROM categories c
JOIN relationships r ON c.cat_id = r.cat_id
JOIN products p ON r.prod_id = p.prod_id
WHERE c.name = 'Books' -- or specify parameter like #Books
In SQL you often join related tables and beginners tend to join, whatever the situation. I would not recommend this. In your case you want to select products. If you only want to show products data, select from products only. You want to select products that are in the category 'Books' (or for which exists an entry in category 'Books'). Hence use an IN or EXISTS clause in order to find them:
select * from products
where prod_id in
(
select prod_id
from relationships
where cat_id = (select cat_id from categories where name = 'Books')
);
Thus you get a well structured query that tells the reader easily how the tables are related and what data you are actually interested in. Later, with different tables and data to select, this may keep you from duplicate result rows that you must get rid of by using DISTINCT or from getting wrong aggregates (sums, counts, etc.), because of mistakenly considering records multifold.
try this:
select p.Prod_id,p.name
from products p inner join relationships r on
p.prod_id = r.prod_id
where r.cat_id = (select cat_id from categories where name = 'books')
or
select p.Prod_id,p.name
from products p inner join relationships r on
p.prod_id = r.prod_id inner join categories c on c.cat_id = r.cat_id
where c.name = 'books'
SELECT *
FROM
productinfo as p ,
category as c
WHERE
c.id IN (p.category) AND
p.pid='T3'
WHERE p.category will return (1,2,3,4,5) from product info table which the id of the category.
Now i need category name used for T3 [product Id] ,but i am getting only the first category name.
Your base query is the following
SELECT * FROM productinfo as p WHERE p.pid = 'T3';
Now you need to pull in categories, per product. This is a many to one relationship, so you need a LEFT JOIN.
SELECT * FROM productinfo as p
LEFT JOIN category as c ON c.id = p.category
WHERE p.id = 'T3'
You need to learn the different types of joins and how they are used. Whenever I see someone use 'FROM table1, table2' 90% of the times it means they don't understand joins and they need a LEFT JOIN instead.
Edit based on your comment
Your datamodel is flawed. Since a product can contain multiple categories, this is really a many-to-many relationship. You should create a product_category table that connects product id's with category id's.