How to do correct inner join over this query? - mysql

SELECT p.product_id, p.quantity, p.price, pd.name, pd.description
FROM product AS p
INNER JOIN product_description AS pd ON p.product_id = pd.product_id
WHERE p.product_id = 1 AND pd.landuage_id = 5
In this query, only one condition exists, p.product_id in this case, but the other condition pd.landuage_id does not exist. I want the request to be executed, whether it exists. How to do it ?

It's possible duplicate, but right answer is:
SELECT p.product_id, p.quantity, p.price, pd.name, pd.description
FROM product p
LEFT JOIN product_description pd ON p.product_id = pd.product_id AND pd.language_id = 5
WHERE p.product_id = 1;

Related

How to use IN operator with AND operator in WHERE clause in SQL...?

I am using this database query in my CodeIgniter model.
SELECT
p.product_id,
p.product_name,
p.product_photo,
p.size,
p.price,
p.status,
p.product_image_path
FROM
products AS p
LEFT JOIN
product_category AS pc
ON
p.product_id = pc.product_id
LEFT JOIN
vendor_products AS vp
ON
vp.product_id = pc.product_id
WHERE
pc.category_id = 2
AND
vp.vendor_id = 36
AND
pc.subcategory_id IN (1,2)
AND
pc.subcategory_value_id IN (1,4)
And it returning me:
I want those products only who fills all conditions of sub_category_value_id. Now it is returning all the conditions.
I am new to database and don't know much about queries.
Below query will give you distinct products with product_id and product_name on basis of given vendor_id, category_id, subcategory_id's and subcategory_value_id's.
Let me know if this works for you!
SELECT
DISTINCT p.product_id,
p.product_name
FROM products AS p
LEFT JOIN product_category AS pc ON p.product_id = pc.product_id
LEFT JOIN vendor_products AS vp ON p.product_id = vp.product_id
LEFT JOIN subcategories AS sc ON sc.subcategory_id = pc.subcategory_id
LEFT JOIN subcategories_value AS scv ON scv.subcategory_value_id = pc.subcategory_value_id
WHERE vp.vendor_id = 2
AND vp.category_id = 2
AND pc.subcategory_id IN (1, 2)
AND scv.subcategory_value_id IN (1, 4)
ORDER BY p.product_id;
It seems like you shouldn't use left join to product_category table. The LEFT JOIN keyword returns all records from the left table (product_category) Please try like below:
SELECT
p.product_id,
p.product_name,
p.product_photo,
p.size,
p.price,
p.status,
p.product_image_path
FROM
products AS p
INNER JOIN
product_category AS pc
ON
p.product_id = pc.product_id
LEFT JOIN
vendor_products AS vp
ON
vp.product_id = pc.product_id
WHERE
pc.category_id = 2
AND
vp.vendor_id = 36
AND
pc.subcategory_id IN (1,2)
AND
pc.subcategory_value_id IN (1,4)
You want group by and having. It is a little unclear what you mean by "all conditions", but it would look something like this:
SELECT p.*
FROM products p JOIN
product_category pc
ON p.product_id = pc.product_id JOIN
vendor_products AS vp
ON vp.product_id = pc.product_id
WHERE pc.category_id = 2 AND
vp.vendor_id = 36 AND
(pc.subcategory_id, pc.subcategory_value_id) IN ( (1, 1), (2, 4) )
GROUP BY p.product_id -- this is okay because it is presumably the primary key
HAVING COUNT(DISTINCT pc.subcategory_id) = 2;
Notes:
The WHERE clause turns the LEFT JOIN into an INNER JOIN, so use the right JOIN.
I assume you want pairs of values from the subcategory table.
The HAVING clause insists on both subcatgories matching.

how to Return productid in this example mysql?

how to Return productid who those filterid equal x and y.
this is select and return table
query :
SELECT p.product_id,pf.filter_id
FROM oc_product p
LEFT JOIN oc_product_filter pf
on p.product_id=pf.product_id
where p.product_id in(96621,97026) and pf.filter_id in (1901,1855 )
group by p.product_id,pf.filter_id
The result of the processing:
product_id filter_id
96621 1855
96621 1901
97026 1901
but i want to get product_id who filter_id=1855 and filter_id=1901.
want to show only product_id=96621 and not return product_id=97026
main query :
SELECT p.product_id
FROM oc_category_path cp
LEFT JOIN oc_product_to_category p2c
ON (cp.category_id = p2c.category_id)
LEFT JOIN oc_product_filter pf
ON (p2c.product_id = pf.product_id)
LEFT JOIN oc_product p
ON (pf.product_id = p.product_id)
LEFT JOIN oc_product_description pd
ON (p.product_id = pd.product_id)
LEFT JOIN oc_product_to_store p2s
ON (p.product_id = p2s.product_id)
WHERE pd.language_id = 2 AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = 0
AND cp.path_id = 86125
AND pf.filter_id in(1901,1855)
GROUP BY p.product_id
ORDER BY p.price DESC, p.sort_order
try and test:
1.#GordThompson:
this result
2.#Edward Mendez
this result
Use OR instead of AND clause .
WHERE product_id in () OR filter_id in () OR product_id not in ()
Remove the product_id from your IN clause for 97026. Also remove the group by since there are no aggregating functioning.
SET #product_id = xxx
SET #filter_id = xxx
SELECT p.product_id,pf.filter_id
FROM oc_product p
LEFT JOIN oc_product_filter pf
on p.product_id=pf.product_id
where p.product_id in(#product_id) and pf.filter_id in (filter_id)
#group by p.product_id,pf.filter_id
If you want a list of product_id values that have both filter_id=1901 and filter_id=1855 you can use
SELECT product_id
FROM oc_product_filter
WHERE filter_id IN (1901,1855)
GROUP BY product_id
HAVING COUNT(*) = 2
or, if the table may have more than one instance of a specific filter_id for a given product_id you can use
SELECT t.product_id
FROM
(
SELECT DISTINCT product_id, filter_id
FROM oc_product_filter
) t
WHERE t.filter_id IN (1901,1855)
GROUP BY t.product_id
HAVING COUNT(*) = 2

Missing Data in mysql query, Need conditional statement in inner join

I have been having issues with missing data when I run the following query.
There are some products which has special price, stored in table oc_product_special and some products has regular price stored in table oc_product.
I figured out that it is only showing data if there is a special price in table oc_product_special. it is omitting any data where there is no special price and only regular price. I am not sure how to fix this problem. How and where i can add conditional statement or something like
if there is a regular price present and no special price then show regular price and 0 for special price.
SELECT
pd.name AS 'Product Name',
p.model AS UPC,
p.quantity AS 'Quantity',
p.price AS 'Regular Price',
ps.price AS 'Special Price',
p.cost AS 'COST',
p.status AS 'Status'
FROM oc_product p
INNER JOIN oc_product_description pd
ON pd.product_id = p.product_id
INNER JOIN oc_product_special ps
ON ps.product_id = p.product_id
INNER JOIN oc_manufacturer m
ON p.manufacturer_id = m.manufacturer_id
INNER JOIN oc_product_to_category p2c
ON p2c.product_id = p.product_id
INNER JOIN oc_category c
ON c.category_id = p2c.category_id
INNER JOIN oc_category_description cd
ON c.category_id = cd.category_id
WHERE
c.category_id = 37 OR c.parent_id = 37
GROUP BY pd.name ORDER BY m.name ASC
Use LEFT JOIN, which will retain records on the left side of the join even if they do not match to anything on the right side:
SELECT COALESCE(pd.name, 'NA') AS 'Product Name',
p.model AS UPC,
p.quantity AS 'Quantity',
p.price AS 'Regular Price',
COALESCE(ps.price, 0.0) AS 'Special Price',
p.cost AS 'COST',
p.status AS 'Status'
FROM oc_product p
LEFT JOIN oc_product_description pd
ON pd.product_id = p.product_id
LEFT JOIN oc_product_special ps
ON ps.product_id = p.product_id
INNER JOIN oc_manufacturer m
ON p.manufacturer_id = m.manufacturer_id
INNER JOIN oc_product_to_category p2c
ON p2c.product_id = p.product_id
INNER JOIN oc_category c
ON c.category_id = p2c.category_id
INNER JOIN oc_category_description cd
ON c.category_id = cd.category_id
WHERE c.category_id = 37 OR
c.parent_id = 37
GROUP BY pd.name
ORDER BY m.name
Explanation:
In a LEFT JOIN, when a record on the left side of the join does not match to anything on the right side, the columns from the right side will all appear as NULL in the result set. I used the COALESCE function in my query, which will conditionally replace the first argument with the second if the former be NULL. In this case, the special price will be replaced with zero if NULL. I also used it with the product name in case names be missing in some cases.
use left join on oc_product_special
SELECT
pd.name AS 'Product Name',
p.model AS UPC,
p.quantity AS 'Quantity',
p.price AS 'Regular Price',
ps.price AS 'Special Price',
p.cost AS 'COST',
p.status AS 'Status'
FROM oc_product p
INNER JOIN oc_product_description pd
ON pd.product_id = p.product_id
LEFT JOIN oc_product_special ps
ON ps.product_id = p.product_id
INNER JOIN oc_manufacturer m
ON p.manufacturer_id = m.manufacturer_id
INNER JOIN oc_product_to_category p2c
ON p2c.product_id = p.product_id
INNER JOIN oc_category c
ON c.category_id = p2c.category_id
INNER JOIN oc_category_description cd
ON c.category_id = cd.category_id
WHERE
c.category_id = 37 OR c.parent_id = 37
GROUP BY pd.name ORDER BY m.name ASC
Inner join si for matching value in you case somethings there aren't match so ..use left join

How to use Group by in mysql

I'm using this sql query to get the product list from DB.
SELECT distinct P.product_id, B.brand_name, P.product_name, P.product_description, SC.sub_category_name, P.product_image_path
FROM table_products as P
INNER JOIN table_brands as B
ON P.brand_id = B.brand_id
INNER JOIN table_product_categories as PC
ON P.product_id = PC.product_id
INNER JOIN table_subcategories as SC
ON SC.sub_categories_id = PC.category_id
INNER JOIN table_subcategory_categories as SCC
ON SC.sub_categories_id = SCC.subcategory_id
ORDER BY P.product_id DESC";
It works fine for me. But when same product is in multiple subcategories. It gives me a new row. I just wanted to avoid this and wants GROUP by with SC.sub_category_name. So when a product is in multiple categories, all the categories should list in same row.
Current
853 Tops Premium Vermicelli /images/tops/853.png Noodles
853 Tops Premium Vermicelli /images/tops/853.png Vermicelli
Expecting
853 Tops Premium Vermicelli /images/tops/853.png Noodles, Vermicelli
You can use GROUP_CONCAT() for that purpose, grouping by SC.sub_category_name and remove the distinct. Something like
SELECT P.product_id,
B.brand_name,
P.product_name,
P.product_description,
GROUP_CONCAT(SC.sub_category_name) as sub_cat_list,
P.product_image_path
FROM table_products P
INNER JOIN table_brands B
ON P.brand_id = B.brand_id
INNER JOIN table_product_categories PC
ON P.product_id = PC.product_id
INNER JOIN table_subcategories SC
ON SC.sub_categories_id = PC.category_id
INNER JOIN table_subcategory_categories SCC
ON SC.sub_categories_id = SCC.subcategory_id
GROUP BY P.product_id
ORDER BY P.product_id DESC;

Get products based on user selected options in MYSQL

I want products that have ALL the options in the IN clause. Here is my SQL:
SELECT
p.title, p.price FROM products AS p, product_options AS po
WHERE
p.product_id = po.product_id
AND
po.product_option_id IN (5,1,38,39)
GROUP BY
p.product_id;
If you want to return the results that have all of those options, then you can use:
SELECT p.title, p.price
FROM products AS p
INNER JOIN product_options AS po
ON p.product_id = po.product_id
WHERE po.product_option_id IN (5,1,38,39)
GROUP BY p.product_id
HAVING COUNT(DISTINCT po.product_option_id) = 4;
See SQL Fiddle with Demo