Mysql - Inner Join - get the non associate results - mysql

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
)

Related

MYSQL SELECT with INNER JOIN with multiple WHERE/CONDITIONS from the same column

I need to perform a SELECT on the PRODUCTS table
that only returns result if the conditions of the PRODUCTS_DETAILS table are true
follow the sql:
select p.* from products p
join products_details pd
on p.id = pd.id_product
WHERE pd.details = 'quadra mar'
AND pd.details = 'prédio novo'
however when I put two or more "AND" it does not return results
objective: search for all products that have the "where" details
Try,
SELECT p.*
FROM products p
INNER JOIN product_details pd ON p.id = pd.id_product
AND pd.details IN ('quadra mar', 'prédio novo');
Take a look in your WHERE clause, I think an OR condition will fix your issue too.
... WHERE pd.details = 'quadra mar' OR pd.details = 'predio novo'
And if you want only products that contains all the conditions in where clause, you can try:
SELECT pd.id_product, pd.details
FROM products p
INNER JOIN product_details pd ON p.id = pd.id_product
AND pd.details IN ('quadra mar', 'prédio novo')
GROUP BY pd.id_product, pd.details
HAVING COUNT(*) > 1;

How do I get a query to return an array in MYSQL?

The query code
SELECT * FROM products
LEFT JOIN (SELECT * FROM product_images ) as images ON products.id = images.productId
LEFT JOIN (SELECT * FROM product_shippings ) as shipping ON products.id = shipping.productId
WHERE products.id = :productID
I have multiple images in product_images, but it's only returning one instance.
What I want to do is get it all in a associate array, like images containing a list of images, shipping containing a list of shipping items, etc.
I know how to achieve this using separate queries, but that is way too slow according to my benchmarks.
So I want something like
{
images:[...],
shipping[...],
productId:2,
productTitle:'Hello'
}
How do I fix this issue?
SELECT *
FROM products
LEFT JOIN product_images as images ON products.id = images.productId
LEFT JOIN product_shippings as shipping ON products.id = shipping.productId
WHERE products.id = :productID
Or, to get commalists (not "arrays")
SELECT p.id, p.title,
GROUP_CONCAT(i.image) AS images,
GROUP_CONCAT(s.shipping) AS shippings
FROM products AS p
LEFT JOIN product_images AS i ON p.id = i.productId
LEFT JOIN product_shippings AS s ON p.id = s.productId
WHERE p.id = :productID
If you take away the GROUP BY you will get all the images for the product.id in the WHERE clause.

Using cases to determine which table should join

I have four tables products, product_histories, vendor_invoices and invoices
This is the query I have developed
SELECT p.product_id, product_name, vendor_name FROM products AS p
INNER JOIN product_histories AS ph ON p.product_id = ph.product_id
CASE
WHEN ph.history_type = "P" THEN
LEFT JOIN vendor_invoices AS vi ON link_id = vi.vi_id
WHEN ph.history_type = "S" THEN
LEFT JOIN invoices AS i ON i.invoice_id = link_id
END
ORDER BY ph_id ASC
What I want that if ph.history_type is P then is should join vendor_invoices and if it is S then it should join invoices. But it says there is a syntax error.
Can anyone help me out with it? Or could show a better way to achieve this problem.

Simple Query, Huge tables

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 );

How to remove a row if sub query returns null value?

I have following query.
select
Product.*,
(
select
group_concat(features.feature_image order by product_features.feature_order)
from product_features
inner join features
on features.id = product_features.feature_id
where
product_features.product_id = Product.id
and product_features.feature_id in(1)
) feature_image
from products as Product
where
Product.main_product_id=1
and Product.product_category_id='1'
I want to bypass the row if feature_image is empty.
Your query looks a bit strange because you are doing most of the work in a subquery:
select p.*, (select group_concat(f.feature_image order by pf.feature_order)
from product_features pf inner join
features f
on f.id = pf.feature_id
where pf.product_id = p.id and pf.feature_id in (1)
) as feature_image
from products p
where p.main_product_id=1 and p.product_category_id='1';
A more common way to phrase the query is as an inner join in the outer query:
select p.*, group_concat(f.feature_image order by pf.feature_order) as feature_image
from products p join
product_features pf
on pf.product_id = p.id and pf.feature_id in (1) join
features f
on f.id = pf.feature_id
where p.main_product_id=1 and p.product_category_id='1'
group by p.id;
This will automatically include only products that have matching features. You would use left outer join to get all products.