Combine results from different queries - mysql

I have a simplified table setup as following:
Table 1 (products)
product_id product_parent_id
646 45
Table 2 (category)
product_id category_name
45 category_1
Table 3 (product_names)
product_id slug
45 product45-details
646 product646-details
For product_id 646 I would like to get the category of product_id 45 and the slug of product 646 and combine them into one output.
So basically the result should be:
id link
646 category_1/product646-details-detail
So far I have the following:
select product_id, CONCAT('I.category_name,'/',E.slug,'-detail') as link from products C left join product_names E on C.product_parent_id=E.product_id left join category H on E.product_id=H.product_id where C.product_id > 1 group by C.product_id
What would be the approach to get the result for E.slug based on the product_id and not the parent_parent_id

You can join:
select p.product_id, c.category_name, pn.slug
from products p
inner join category c on c.product_id = p.product_parent_id
inner join product_names pn on pn.product_id = p.product_id
where p.product_id = 646

Related

php - Check same column twice in mysqli query

I have 3 tables in my php based system.
Those tables are product, category, product_categories.
Product
pid | product_name | price
1 | Nike T-Shirt | 23
Category
cid | category_name
1 | Men
2 | Women
Product_categories
pcid | cid | pid
1 | 1 | 1
2 | 2 | 1
That means, 1 product may be in both multiple categories.
Now I am developing the product search section with filter.
If a user select both categories, all the products in selected categories should display.
Example : If a user select both Men & Women, Nike T-Shirt should be displayed.
The query I used:
select p.*
from products p
left join product_categories pc on pc.pid=p.pid
WHERE pc.cid ='1' AND pc.cid = '2'
But it not returning correct products.
Where is the error?
You want conditions that span over multiple rows, which suggests aggregation. You can join the tables, group by product, and use the having clause for filtering:
select p.id, p.product_name, p.price
from product p
inner join product_category pc on pc.pid = p.pid
inner join category c on c.cid = pc.cid
where c.category_name in ('Men', 'Women')
group by p.pid, p.product_name, p.price
having max(c.category_name = 'Men') = 1 and max(c.category_name = 'Women') = 1
If you can filter by category id rather than by category name, then you need one less join:
select p.id, p.product_name, p.price
from product p
inner join product_category pc on pc.pid = p.pid
where pc.cid in (1, 2)
group by p.pid, p.product_name, p.price
having max(pc.cid= 1) = 1 and max(pc.cid = 2) = 1
Here are few alternatives:
-- All products that are at lest in one of the desired categories
select * from product where product.pid = any (select product_category.pid from product_category where cid = 1 or cid = 2);
-- Products that are in both categories
select * from product where product.pid = any (
select product_category.pid from product_category where cid = 1 or cid = 2 group by pid having count(cid) = 2
);
-- Products with additional information "in how many desired categories they are"
-- You can order by it and/or filter on it
with product_category_matches as (
select pid, count(*) as category_count from product_category where cid in (1, 2) group by pid
)
select *, product_category_matches.category_count from
product inner join product_category_matches on product.pid = product_category_matches.pid
where product_category_matches.category_count > 0 -- Product must be at least in one desired category
order by product_category_matches.category_count desc

Get categories which do not have any product from a particular category

I am trying to write a sql query to get the categories which does not have any of the products from particular category. Let say I have a,b,c,d,e categories and each category have some products. Now I need to get all the categories which done not include products of category a.
Categories table:
id name
1 A
2 B
3 C
4 D
5 E
category_products table:
product_id category_id
1 1
1 2
2 3
2 1
4 3
3 2
3 4
3 5
4 5
Query I used is below which gives B,C,D,E (not as expected)
SELECT DISTINCT c.name FROM category_products AS p
LEFT JOIN categories AS c ON c.id = p.category_id
WHERE p.product_id NOT IN (SELECT DISTINCT product_id FROM category_products where category_id = 1)
ORDER BY c.name
But I need results to be categories D,E which don't have any products from category A.
You need to do one more inner query, e.g.:
SELECT name
FROM categories
where id NOT IN (
SELECT DISTINCT category_id
FROM category_products WHERE
product_id IN (
SELECT product_id FROM category_products WHERE category_id = 1
)
);
This would return D and E.
Here's the SQL Fiddle.
You should use inner join
select distinct t2.name
from category_products t1
inner join Categories t2 on t2.id = t1.category_id
where t1.product_id not in
(select p.product_id
from category_products p
inner join Categories c on c.id = p.category_id
where c.name ='A')
I would be inclined to do this using group by and having:
select pc.product_id
from category_products pc join
categories c
on c.id = pc.category_id
group by pc.product_id
having sum(c.name = 'A') = 0;

find records grouped by two columns in mysql

I want to find out all seller who have uploaded products in categories (electronics,clothing,furniture), so for 3 categories there can be 3 row against each seller . tables I have are
1.category{category_id,name},
2.seller {seller_id,username},
3.products{product_id,seller_id,category_id,title}
Note:There can be maximum 3 result (coz I'm searching in 3 categories) against one seller even if he added more than one product in single category
expected result:
**product_id** **category** **sellerUsername**
101 electronics kuldeep
211 furniture kuldeep
322 clothing kuldeep
167 electronics roman
245 furniture roman
247 clothing dangi
246 furniture dangi
..
..
if you need only the matching relation use inner join
select a.product_id, b.username, c.name
from products as a
inner join seller as b on b.seller_id = a.seller_id
inner join category as c on c.category_id = a.category_id
else use left join
select a.product_id, b.username, c.name
from products as a
left join seller as b on b.seller_id = a.seller_id
left join category as c on c.category_id = a.category_id
The general solution to your problem is to join the three tables together and then aggregate by seller and category. In my solution, I have arbitraily chosen the max product ID, in the absence of any logic for doing otherwise. The query is slightly tricky, in that we need to additionally join this result again to the category and seller tables to get the human readable category and seller names. The reason for this is the GROUP BY query should ideally be done by ID and not name, since conceivably two categories (or sellers) could have the same name but have different IDs.
SELECT t3.product_id,
COALESCE(t1.name, 'NA'),
COALESCE(t2.username, 'NA')
FROM
(
SELECT MAX(p.product_id) AS product_id,
c.category_id,
s.seller_id
FROM products p
LEFT JOIN category c
ON p.category_id = c.category_id
LEFT JOIN seller s
ON p.seller_id = s.seller_id
WHERE c.name IN ('electronics', 'clothing', 'furniture')
GROUP BY s.seller_id,
c.category_id
) t1
LEFT JOIN category t2
ON t1.category_id = t2.category_id
LEFT JOIN seller t3
ON t1.seller_id = t3.seller_id
Check Below Code.
SET #row_number:=0;
SET #db_names:= '';
SET #db_names2:= '';
select product_id,name as category ,username as sellerUsername
from (
select a.product_id, c.name ,b.username,
#row_number:=CASE WHEN #db_names=username and #db_names2=name THEN #row_number+1
ELSE 1 END AS row_number,#db_names:=username AS username2,#db_names2:=name AS name2
from products as a
left join seller as b on b.seller_id = a.seller_id
left join category as c on c.category_id = a.category_id
where name IN ('electronics', 'clothing', 'furniture')
)a where row_number < 2
order by sellerUsername,name;
Output :

Write query without join and using subquery

I want to rewrite the join query with sub-query like IN(), ANY() operator.
Data set:
*categories*
categoryID name
5 ROD
7 CEMENT
*products*
productID categoryID name
7 5 BSRM 10mm
9 5 KSRM 5mm
10 5 Julius
11 7
12 5 BSRM 25mm
*sale_products*
saleID productID
118 9
119 9
120 9
121 9
122 12
123 12
124 12
This is my query to read saleID, product name and category name for which already have sold.
My query is:
SELECT sale_products.saleID, products.name, categories.name
FROM categories
INNER JOIN (products, sale_products)
ON categories.categoryID = products.categoryID
AND products.productID = sale_products.productID
Now I want to the result set without join and with the sub-query methodology.
I try in this way:
SELECT categories.name
FROM categories
WHERE categories.categoryID IN
(SELECT products.categoryID
FROM products
WHERE products.productID in
(SELECT sale_products.productID FROM sale_products))
this query only give me the category name but I need also saleID, product name.
Your original query looks queer. Why do you cross join products and sale_products?
It should better be:
select sp.saleid, p.name as product, c.name as category
from sale_products sp
join products p on p.productid = sp.productid
join categories c on c.categoryid = p.categoryid;
This is the straight-forward way to show the data. You can use subqueries instead, but I see no sense in it:
select
sp.saleid
(
select p.name
from products p
where p.productid = sp.productid
) as product,
(
select c.name
from categories c
where c.categoryid = p.categoryid
) as category
from sale_products sp;
Here is yet another query with subqueries. Again without any benefit over the simple query using direct joins on the tables.
select sp.saleid, p.name as product, c.name as category
from sale_products sp
join (select productid, name from products) p on p.productid = sp.productid
join (select categoryid, name from categories) c on c.categoryid = p.categoryid;

Join two table. One column using SUM

I need a little help with a MySQL query.
I have two tables one table is a list of product and one table is a list of warehouses quantity
product:
product_id product_name
1 name1
2 name2
3 name3
warehouse_product
id warehouse_id product_id product_quantity
1 1 1 15
2 2 1 30
3 1 2 100
4 2 2 30
5 1 3 20
6 2 3 40
The results Im looking to get from the above data would be
product_id product_name product_quantity
1 name1 45
2 name2 130
3 name3 60
I've tried many query but it's not working. My query is:
SELECT
product_id as product_id, SUM(quantity) as quantity
FROM
(SELECT
p.product_id as product_id, wp.product_quantity as quantity
FROM
product as p
LEFT JOIN warehouse_product as wp ON p.product_id = wp.product_id
WHERE
product_active = 1)
Try this:
SELECT p.product_id, p.product_name, SUM(wp.quantity) as quantity
FROM product as p
LEFT JOIN warehouse_product as wp
ON p.product_id = wp.product_id
AND product_active = 1
GROUP BY p.product_id, p.product_name
After JOINing the two tables you need to use GROUP BY so that SUM of quantity can be calculated for each product.
select p.product_id,p.product_name,sum(product_quantity) as 'product_quantity'
from product p inner join warehouse_product whp on
whp.product_id=p.product_id group by whp.product_id
select p.product_id, p.product_name,sum(w.product_quantity)
from
product p
inner join
warehouse_product w
on
p.product_id = w.product_id
group by w.product_id
order by p.product_name;
SELECT P.productid,
P.ProductName,
Sum(W.product_quantity) As quantity
FROM Product AS P
LEFT JOIN warehouse_product AS W
ON P.productid = W.productid
GROUP BY P.ProductId , P.ProductName
SQLFiddle