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`
Related
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.
My query gets the results of these products based on if they exist in a separate table index. I am trying to get a count of all the instances where they exist so I can ORDER the results by relevance. Everything I try seems to return the variable #priority as 0. Any ideas?
Maybe it is better to use join statements?
Thank you for your help. Here is my MySQL query:
SELECT `products` . * , #priority
FROM `products`
LEFT JOIN productstypes_index ON productstypes_index.product_id = products.id
WHERE (
EXISTS (
SELECT *
FROM `productstypes_index`
WHERE `productstypes_index`.`product_id` = `products`.`id`
AND `productstypes_index`.`_type_id` = '1'
)
AND (
(
(
EXISTS (
SELECT #priority := COUNT( * )
FROM `producthashtags_index`
WHERE `producthashtags_index`.`product_id` = `products`.`id`
AND `producthashtags_index`.`producthashtag_id` = '43'
)
)
AND (
EXISTS (
SELECT #priority := COUNT( * )
FROM `producthashtags_index`
WHERE `producthashtags_index`.`product_id` = `products`.`id`
AND `producthashtags_index`.`producthashtag_id` = '11'
)
)
)
)
)
ORDER BY `updated_at` DESC;
You could do without those exists, and without variables. Also, a left join has no sense if you have an exists condition on the joined table. Then you might as well do the more efficient inner join and put the extra type condition in the join condition.
The priority can be calculated by a count over the hash tags, but only those with id in ('43', '11').
SELECT products.*
count(distinct producthashtags_index.producthashtag_id) priority
FROM products
INNER JOIN productstypes_index
ON productstypes_index.product_id = products.id
AND productstypes_index._type_id = '1'
INNER JOIN producthashtags_index
ON producthashtags_index.product_id = products.id
AND producthashtags_index.producthashtag_id in ('43', '11')
GROUP BY products.id
ORDER BY updated_at DESC;
MySQL ignores the SELECT list in EXISTS subquery, so it makes no difference what you type in there. This is documented here.
An approach using joins would look like below:
SELECT p.id,
COUNT(case when phi.product_id is not null then 1 end) AS instances
FROM products p
INNER JOIN productstypes_index pti ON pti.product_id = p.id AND pti.`_type_id` = 1
LEFT JOIN producthashtags_index phi ON phi.product_id = p.id AND phi.producthashtag_id IN (11,43)
GROUP BY p.id
ORDER BY instances DESC;
I have removed additional backticks where I believe they are not neccessary and also if your id columns in tables are integers, you do not need quotation marks.
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 );
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
I have a table
'products' => ('product_id', 'name', 'description')
and a table
'product_price' => ('product_price_id', 'product_id', 'price', 'date_updated')
I want to perform a query something like
SELECT `p`.*, `pp`.`price`
FROM `products` `p`
LEFT JOIN `product_price` `pp` ON `pp`.`product_id` = `p`.`product_id`
GROUP BY `p`.`product_id`
ORDER BY `pp`.`date_updated` DESC
As you can probably guess the price changes often and I need to pull out the latest one. The trouble is I cannot work out how to order the LEFT JOINed table. I tried using some of the GROUP BY functions like MAX() but that would only pull out the column not the row.
Thanks.
It appears that it is impossible to use an ORDER BY on a GROUP BY summarisation. My fundamental logic is flawed. I will need to run the following subquery.
SELECT `p`.*, `pp`.`price` FROM `products` `p`
LEFT JOIN (
SELECT `price` FROM `product_price` ORDER BY `date_updated` DESC
) `pp`
ON `p`.`product_id` = `pp`.`product_id`
GROUP BY `p`.`product_id`;
This will take a performance hit but as it is the same subquery for each row it shouldn't be too bad.
You need to set aliases properly I think and also set what you are joining on:
SELECT p.*, pp.price
FROM products AS p
LEFT JOIN product_price AS pp
ON pp.product_id = p.product_id
GROUP BY p.product_id
ORDER BY pp.date_updated DESC
This will give you the last updated price:
select
p.*, pp.price
from
products p,
-- left join this if products may not have an entry in prodcuts_price
-- and you would like to see a null price with the product
join
(
select
product_price_id,
max(date_updated)
from products_price
group by product_price_id
) as pp_max
on p.product_id = pp.product_id
join products_price pp on
pp_max.prodcuts_price_id = pp.products_price_id
Mysqlism:
SELECT p.*, MAX(pp.date_updated), pp.price
FROM products p
LEFT JOIN product_price pp ON pp.product_id = p.product_id
GROUP BY p.product_id
Will work on some RDBMS:
SELECT p.*, pp.date_updated, pp.price
FROM products p
LEFT JOIN product_price pp ON pp.product_id = p.product_id
WHERE (p.product_id, pp.date_updated)
in (select product_id, max(date_updated)
from product_price
group by product_id)
Will work on most RDBMS:
SELECT p.*, pp.date_updated, pp.price
FROM products p
LEFT JOIN product_price pp ON pp.product_id = p.product_id
WHERE EXISTS
(
select null -- inspired by Linq-to-SQL style :-)
from product_price
WHERE product_id = p.product_id
group by product_id
HAVING max(date_updated) = pp.date_updated
)
Will work on all RDBMS:
SELECT p.*, pp.date_updated, pp.price
FROM products p
LEFT JOIN product_price pp ON pp.product_id = p.product_id
LEFT JOIN
(
select product_id, max(date_updated) as recent
from product_price
group by product_id
) AS latest
ON latest.product_id = p.product_id AND latest.recent = pp.date_updated
And if nate c's code intent is to just get one row from product_price, no need to table-derive (i.e. join (select product_price_id, max(date_updated) from products_price) as pp_max), he might as well just simplify(i.e. no need to use the product_price_id surrogate primary key) it like the following:
SELECT p.*, pp.date_updated, pp.price
FROM products p
LEFT JOIN product_price pp ON pp.product_id = p.product_id
WHERE pp.date_updated = (select max(date_updated) from product_price)