Write query without join and using subquery - mysql

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;

Related

Combine results from different queries

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

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 :

mysql count subtables and its subtables for its main table

Table 1 - Category
id | name
Table 2 - subcat
id | cid(category.id) | name
Table 3 - products
id | cid(category.id) | sid(subcat.id) | name
select a.* , count(b.id) as total
from category a left join
subcategory b on a.id=b.cid
group by a.id order by a.name
this gives the count of sub categories for each category
and I can run seperately for products so that i will get count of products for each category
what I want is the count of subcategories and the count of products for each category. How to form the query?
It should be like catename, count of (sub categories) and count of (products)
Because you may have sub-categories for a given category, but no products actually listed for such sub-category, you might not get the results you expect... This should catch both for you
select a.id,
a.name,
BySubCat.AvailableSubCategories,
ByProduct.ActualSubCats,
ByProduct.ProductCount
from
category a
left join
( select cid, count(*) as AvailableSubCategories
from subcat
group by cid ) BySubCat
on a.id = BySubCat.cid
left join
( select cid,
count( distinct sid ) as ActualSubCats,
count(*) ProductCount
from
products
group by
cid ) ByProduct
on a.id = ByProduct.cid
order by
a.name
Try this:
select c.name,count(sc.id),count(sub.pcount)
from subcat sc
inner join
(
select p.sid as subid, count(p.id) as pcount from Products p
inner join subcat sc on sc.id = p.sid
group by p.sid
) sub
on sub.subid = sc.id
inner join Category c on c.id = sc.cid
group by sc.id,sub.pcount

mysql count, distinct, join? Confusion

i have 2 tables:
tblItems
ID | orderID | productID
1 1 2
2 1 2
3 2 1
4 3 2
tblProducts
productID | productName
1 ABC
2 DEF
im attempting to find the most popular Product based on whats in "tblItems", and display the product Name and the number of times it appears in the tblItems table.
i can get mysql to count up the total like:
$sql="SELECT COUNT(productID) AS CountProductID FROM tblItems";
but i can't figure out how to join the products table on..if i try LEFT JOIN the query goes horribly wrong
hopefully thats not too confusing..thankss
Are you simply trying to find the count of orders by product like so:
Select P.ProductName, Count(*)
From tblItems As I
Join tblProducts As P
On P.ProductId = I.ProductId
Group By P.ProductName
I think you may be looking for something like:
SELECT tblProducts.productName, COUNT(tblItems.ID)
FROM tblProducts
LEFT JOIN tblItems USING(productID)
GROUP BY tblProducts.productID
SELECT count(i.productID) AS cnt, p.productName FROM tblItems AS i
LEFT JOIN tblProducts AS p ON p.productID = i.productID
GROUP BY i.productID
ORDER BY cnt desc