Simple Query, Huge tables - mysql

I have 2 tables:
Products ( 53k rows )
Product Categories ( 170k rows )
I'm trying to find uncategorized products with this query:
SELECT * FROM `jp_harley_products`
WHERE product_id NOT IN
(SELECT p_cat_product_id
FROM jp_harley_product_cats )
also tried this:
SELECT p.product_id,pc.p_cat_product_id
FROM `jp_harley_products` p
LEFT JOIN `jp_harley_product_cats` pc on pc.p_cat_product_id = p.product_id
My PHPmyAdmin can't handle this, as it doesn't show any results.
In harley_product_cats I have columns like: Product ID, Cat ID, so basically I want to get these products which doesn't have any relation in harley_product_cats
Can anyone help me with this?

You need to include a IS NULL for the LEFT JOIN one to work.
SELECT p.product_id, pc.p_cat_product_id
FROM `jp_harley_products` p
LEFT JOIN `jp_harley_product_cats` pc on pc.p_cat_product_id = p.product_id
WHERE p.product_id IS NULL
Or try using WHERE NOT EXISTS
SELECT p.product_id, pc.p_cat_product_id
FROM `jp_harley_products` p
WHERE NOT EXISTS (SELECT 1 FROM jp_harley_product_cats pc WHERE p.product_id = pc.p_cat_product_id );

Related

Mysql - Inner Join - get the non associate results

i need to do a query.
For example, i have products and sub products. Sub products can be associate to products, so i need a query that give me the results of sub products that are not associate to a certain product.
I did a inner join but is not right.
SELECT *
FROM subProducts
INNER JOIN products on subProducts.id != products.idSubProduct
WHERE products.id = $idProduct
Thank's
Use an outer join instead with a null check:
SELECT *
FROM subProducts
LEFT JOIN products on subProducts.id = products.idSubProduct
AND products.id = $idProduct
WHERE products.id IS NULL
There are other ways to do this as well -- not in and not exists can work similarly. Here's using not exists:
SELECT *
FROM subProducts s
WHERE NOT EXISTS (
SELECT 1
FROM products p
WHERE p.idSubProduct = s.id AND p.id = $idProduct
)

Find missing combination of columns from two mysql tables

I have one product table like this:
productid categoryid
and another category table like this:
categoryid parentid
would like to find rows missing from product table
select distinct c.parentid, pc.productid, from products_categories pc
join categories c on pc.categoryid = c.categoryid
where concat(pc.productid,'-',c.parentid) not in (
select distinct concat(productid,'-',categoryid) from products_categories
)
however this is extremely slow. is there a way to do this with joins instead of the not in concat line? the concat is used to account for all possible combos.
Everytime you are adding a prefix productID & - to either parentID or categoryID.
You can try this:
SELECT DISTINCT c.parentid, pc.productid
FROM products_categories pc
JOIN categories c on pc.categoryid = c.categoryid
WHERE c.parentid NOT IN (
SELECT DISTINCT categoryid FROM products_categories
)
Edit 1: doesnt account for all combos
SELECT DISTINCT c1.parentid, pc.productid
FROM products_categories pc
INNER JOIN categories c1 ON pc.categoryid = c1.categoryid
LEFT JOIN categories c2 ON c1.parentid = c2.categoryid
WHERE c2.categoryid IS NULL
To find what is in tbl_x but not in tbl_y, do this
SELECT ...
FROM tbl_x
LEFT JOIN tbl_y USING(...)
WHERE tbl_y.id IS NULL;
The construct IN ( SELECT ... ) is very poorly optimized. LEFT JOIN is well optimized (assuming suitable index).

Get all rows from table whose key isn't matched in another table

I have a table called products and a table called product_description
They both have a column called product_id which is used to link them.
How do I get all the rows from the product_description table whose product_id is
not found in the products table?
I tried this:
SELECT *
FROM `product_description`
JOIN product ON product_description.product_id = product.product_id
WHERE product_description.product_id != product.product_id
But that returned zero rows.
Use a left outer join and find where there are no matches:
SELECT product_description.*
FROM `product_description` left outer join product
on product_description.product_id = product.product_id
where product.product_id is null
INNER JOIN filters out mismatches. That's why you don't get any results with your query. What you need is an OUTER JOIN
SELECT *
FROM product_description d LEFT JOIN product p
ON d.product_id = p.product_id
WHERE p.product_id IS NULL
or you can use a subquery with NOT IN
SELECT *
FROM product_description
WHERE product_id NOT IN
(
SELECT product_id
FROM product
)
or with NOT EXISTS
SELECT *
FROM product_description d
WHERE NOT EXISTS
(
SELECT *
FROM product
WHERE product_id = d.product_id
)
Here is SQLFiddle demo for all above-mentioned queries
To better understand JOINs see A Visual Explanation of SQL Joins

SQL left joing with additional where clause

products (products_id, name, type)
orderform (orderform_id, product_id, country_id, price)
I want to get all the products that don't exist in the orderform table for a certain country_id.
The following is incorrect and I understand that there a quicker ways, speed is not really an issue just getting the correct result set.
SELECT * FROM products p
left JOIN orderform o ON o.product_id = p.product_id
WHERe o.product_id is NULL AND o.jur_id = 10
Thanks guys and gals
SELECT *
FROM products p
WHERE product_id NOT IN(SELECT product_id
FROM orderform
WHERE jur_id = 10);
Also try to move the extra condition to the join condition:
SELECT *
FROM products p
left JOIN orderform o ON o.product_id = p.product_id
AND o.jur_id = 10
WHERe o.product_id is NULL;
It will look like this! (not the best approach though)
SELECT * FROM products p
left JOIN (select * from orderform WHERe product_id is NULL AND jur_id = 10) o ON o.product_id = p.product_id
this one will be simple
SELECT *
FROM products p
WHERE products_id NOT IN (SELECT DISTINCT product_id
FROM orderform
WHERE country_id = 10)
i cant see jur_id in your schema, if you want you can apply that filter too

mysql inner join statement error

I am getting the following error:
1052 - Column 'product_id' in field list is ambiguous
When I run the following:
SELECT `product_id`, `product_name`
FROM `products`
INNER JOIN `products_has_product_category`
ON `products.product_id` = `products_has_product_category.product_id`
AND `products_has_product_category.category_id` = 1
ORDER BY `products.product_name`
My PRODUCTS table has
product_id, product_name, etc
My products_has_product_category table has
product_id, category_id
This is my first try at a join, so I appreciate the help!
You need to specify which table the product_id comes from. Since the product_id is in both tables, when you SELECT it you need to specify which table you want the value from. With a table alias:
SELECT p.product_id, p.product_name
FROM `products` p
INNER JOIN `products_has_product_category` pc
ON p.product_id = pc.product_id
AND pc.category_id = 1
ORDER BY p.product_name
Without table aliases:
SELECT `products`.`product_id`, `products`.`product_name`
FROM `products`
INNER JOIN `products_has_product_category`
ON `products.product_id` = `products_has_product_category.product_id`
AND `products_has_product_category.category_id` = 1
ORDER BY `products.product_name`
If I understand your intention correctly, you probably meant WHERE rather than AND:
SELECT `products`.`product_id`, `products`.`product_name`
FROM `products`
INNER JOIN `products_has_product_category`
ON `products.product_id` = `products_has_product_category.product_id`
WHERE `products_has_product_category.category_id` = 1
ORDER BY `products.product_name`