SELECT name,
manufacturer,
prize
FROM products AS p
GROUP BY manufacturer
HAVING prize = (
SELECT Max(prize)
FROM products p1
WHERE p.`id-product` = p1.`id-product`
GROUP BY p1.manufacturer DESC
LIMIT 1
)
And the error is:
#1054 - Unknown column 'shop.p.id.product' in 'where clause'
I think you need correlated subquery instead :
SELECT p.name, p.manufacturer, p.prize
FROM products AS p
WHERE p.prize = (SELECT MAX(p1.prize) FROM products p1 WHERE p1.manufacturer = p.manufacturer);
By this way, you will get manufacturers with highest price.
EDIT : If one product has same prize then you will need PK (Primary/Identity) column that specify unique sequence :
SELECT p.name, p.manufacturer, p.prize
FROM products AS p
WHERE p.pk = (SELECT p1.pk
FROM products p1
WHERE p1.manufacturer = p.manufacturer
ORDER BY p1.prize DESC
LIMIT 1
);
If you are running with latest version of MySQL, then you can also use ranking function :
SELECT p.*
FROM (SELECT p.name, p.manufacturer, p.prize,
ROW_NUMBER() OVER (PARTITION BY p.manufacturer ORDER BY p.prize DESC) AS Seq
FROM products AS p
) p
WHERE Seq = 1;
Your query has nothing of that form. I would recommend writing the query by qualifying all column references:
SELECT p.name, p.manufacturer, p.prize
FROM products p
GROUP BY p.manufacturer
HAVING p.prize = (SELECT MAX(p1.prize)
FROM products p1
WHERE p.`id-product` = p1.`id-product`
GROUP BY p1.manufacturer DESC
LIMIT 1
);
MySQL allows the syntax with extra columns in the SELECT that are not in the GROUP BY, so that would not (normally) generate an error. It is not correct, though, by the rules of SQL.
I'm not sure what the subquery is supposed to be doing. If you want the manufacturers with the highest price, then you would not use the GROUP BY in the subquery.
If you want the highest priced product for each manufacturer:
SELECT p.name, p.manufacturer, p.prize
FROM products p
HAVING p.prize = (SELECT MAX(p1.prize)
FROM products p1
WHERE p.manufacturer = p1.manufacturer
LIMIT 1
);
Related
my query is
SELECT productscrapeddatalog.*, product.productname
FROM productscrapeddatalog JOIN product
ON productscrapeddatalog.productID = product.productID
WHERE price = (SELECT MIN(price) FROM productscrapeddatalog ORDER BY productID)
this is my table screenshot
Your approach with a join and filtering in the where clause is ok - but you need to correlate the subquery with the outer query so you get the lowest price per product rathern thatn the overall min:
SELECT l.*, p.productname
FROM productscrapeddatalog l
JOIN product p ON l.productID = l.productID
WHERE l.price = (
SELECT MIN(l1.price)
FROM productscrapeddatalog l1
WHERE l1.productID = t.productID
)
If you are running MySQL 8.0, you can also do this with window functions:
SELECT l.*, p.productname
FROM product p
JOIN (
SELECT l.*, RANK() OVER(PARTITION BY productID ORDER BY price) rn
FROM productscrapeddatalog l
) p ON l.productID = l.productID AND l.rn = 1
You should try this:
SELECT productscrapeddatalog.*, product.productname, MIN(productscrapeddatalog.price)
FROM productscrapeddatalog JOIN product
ON productscrapeddatalog.productID = product.productID
ORDER BY productID
I have a problem with SQL to select same information when I hve lot of clause
the first column is unknow in other clause.
This is my sql expression:
SELECT * ,
(select sum(sell) from product_details where product_details.product_id = products.id) as total ,
(select sell from product_details where product_details.product_id = products.id order by product_details.id desc limit 1) as ysell ,
(select sum(sell) as wsell FROM (select sell from product_details where product_details.product_id = products.id order by product_details.id desc limit 2 ) as weeksell) as wsell
FROM `products`
I try to get information from product and second table is product_details
based on product ID;
ysell = last sell
total = total sell
wsell = limit 7 sell by using sum() and select from the last 7
but whene i run my expression i get error
#1054 - Unknown column 'products.id' in 'where clause'
isn't knowing in this line
(select sum(sell) as wsell FROM (select sell from product_details where product_details.product_id = products.id order by product_details.id desc limit 2 ) as weeksell) as wsell
can you suggest any ideas.
Your problem is that correlation clauses cannot be nested more than one level deep -- hence the reason by products is not seen. One solution is to transform this to conditional aggregation. That is a bit tricky, but here is one method:
SELECT p.* ,
sum(pd.sell) as total,
max(case when pd.id = pdd.max_id then pd.sell end) as ysell,
sum(case when pd.id >= pdd.id7 then pd.sell end) as wsell
FROM products p JOIN
product_details pd
ON pd.product_id = p.id JOIN
(SELECT pd.product_id, MAX(pd.id) as max_id,
SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(pd.id ORDER BY pd.id DESC), ',', 7), ',', -1) as id7
FROM product_details pd
GROUP BY pd.product_id
) pdd
ON pdd.product_id = p.id
GROUP BY p.id; -- reasonable assuming `id` is unique/primary key
Hello guys i have that SQL:
SELECT p.* FROM products p WHERE required_product_id IS NULL
UNION ALL
SELECT p.* FROM products p, orders o WHERE p.required_product_id = o.product_id
AND o.user_id = 1
UNION DISTINCT
SELECT p.`*` FROM products p, orders o WHERE p.id NOT IN (SELECT product_id FROM orders WHERE product_id = p.id AND o.user_id = 1)
AND p.max_buys = 1;
This query first checking if item is purchased and show next item! i want to check if user is purchased that product to return only that product that user is not bought it
table structure = Products: http://prntscr.com/k6ogp4 ,Orders: http://prntscr.com/k6ogrz
max_buys colum on products (if it 1 it can buy it once , if its 0 it can be buyed many times)
In your case I prefer to have a flexible query to manage requirements and also I think that UNION is not required in this case [if your description is complete].
SELECT w.* from (
SELECT
(SELECT count(o.product_id) FROM orders o WHERE o.product_id = p.id AND o.user_id = 1) bought_count,
(SELECT count(q.product_id) FROM orders q WHERE q.product_id = p.required_product_id AND q.user_id = 1) order_depend,
p.*
FROM products p ) w
where
(order_depend>0 or required_product_id is null) and -- unlock order depended products
(max_buys=0 or -- can buy more than once
bought_count=0) -- or not bought yet
order by
order_depend desc, -- dependent products to ordered products in first level
bought_count asc, -- not bought products in second level
recommended desc -- recommended products in third level
You can also manage any other order according to your requirement.
I'm facing a little problem with mysql where clause.
This is the query:
SELECT u.id user
, p.id product_purchased
, p.name product_name
, pl.store_id store
, COUNT(*) occurrences
, total_spent
, total_product_purchased
, pl.registration
FROM purchases_log pl
JOIN user u
ON pl.user_id = u.id
JOIN product p
ON pl.product_id = p.id
JOIN
( SELECT user_id
, SUM(price) total_spent
, COUNT(product_id) total_product_purchased
FROM purchases_log pl
GROUP
BY user_id
) t1
ON u.id = t1.user_id
WHERE pl.store_id IN (1,2,3)
AND occurrences > 1
GROUP
BY user
, product_name
ORDER
BY u.id ASC
, pl.registration ASC;
This is the output error:
Error Code: 1054. Unknown column 'occurrences' in 'where clause' 0.067 sec
I have already tried assign AS to occurrences or using pl.
So, can someone explain me how to correctly define the result of a count function in where clause?
You need to use HAVING instead of COUNT as group by is applied after WHERE clause and hence, it won't know about any group/aggregate columns, e.g/:
SELECT u.id user,p.id product_purchased, p.name product_name, pl.store_id store, COUNT(*) AS occurrences, total_spent, total_product_purchased, pl.registration
FROM purchases_log pl
JOIN user u ON pl.user_id=u.id
JOIN product p ON pl.product_id=p.id
JOIN (SELECT user_id, SUM(price) AS total_spent,COUNT(product_id) AS total_product_purchased FROM purchases_log pl GROUP BY user_id) t1 ON u.id=t1.user_id
WHERE pl.store_id IN (1,2,3)
GROUP BY user, product_name
HAVING COUNT(*) > 1
ORDER BY u.id ASC, pl.registration ASC;
Update
If a user has more than one product associated then it's good to add all the non aggregate columns in GROUP BY to get all the combinations of user and product. The current query will not return all the combinations.
For further optimization, as #strawberry has suggest, you can run EXPLAIN and see which indices are used and whether there is any need to create any new index.
I try to get a list of products with each newest and lowest offer price
Table product:
id | name
Table offer:
id | product_id | price | created | dealer_id
Table invalids:
id | offer_id | status
I have tried:
SELECT * FROM product INNER JOIN
(
SELECT offer.product_id , offer.price
FROM offer
LEFT JOIN invalids
ON offer.id = invalids.offer_id
WHERE invalids.id IS NULL
GROUP BY offer.dealer_id
ORDER BY offer.created DESC
) o
ON o.product_id = product.id
ORDER BY product.name
I have tried an sqlfiddle http://sqlfiddle.com/#!9/32658/3 with this offer values:
(`id`, `price`, `dealer_id`, `product_id`, `created`)
(1,12.60,1,1,'2015-05-17 08:44:45'),
(2,13.00,1,1,'2015-08-17 08:44:45'),
(3,20.00,1,1,'2015-08-17 08:45:30'),
(4,10.00,1,1,'2015-08-17 08:45:46'),
(5,4.00,2,1,'2015-05-17 08:44:11'),
(6,11.00,2,1,'2015-08-17 08:44:46'),
(7,5.00,2,1,'2015-08-17 08:45:31'),
(9,110.00,2,2,'2015-08-17 08:46:58'),
(10,11.00,2,2,'2015-08-17 08:47:12');
Expected value for product ID 1 is offer ID 7 with price 5.
These steps I think I must realize:
Order offers by created and group by dealer_id to get newest entries
Take result from step 1 and order it by price to get smallest price.
Make this for all products
Maybe I must use a second SELECT FROM offer with GROUP BY and ORDER BY but how do I get I the product_id from the first (outer) select?
Well I would start by getting the latest date for each product offer like this:
SELECT product_id, MAX(created) AS latestOffer
FROM offer
GROUP BY product_id;
Once you have that, you can join it to the original table to get that offer:
SELECT o.*
FROM offer o
JOIN(
SELECT product_id, MAX(created) AS latestOffer
FROM offer
GROUP BY product_id) tmp ON tmp.product_id = o.product_id AND tmp.latestOffer = o.created;
Here is an SQL Fiddle example.
This query should help you:
SELECT *
FROM product
JOIN (
SELECT product_id, min(price) as minPrice, max(created) as newestOffer
FROM offer
WHERE id NOT IN (SELECT offer_id FROM invalids)
GROUP BY 1
) as b
ON product.id = b.product_id
A shot in the dark based on what I understand you to be after...
lots of nested subqueries.. keep thinking there's got to be a better way...
SELECT OO.ID, OO.Price, OO.Dealer_Id, OO.Product_ID, OO.created, P.name
FROM Offer OO
INNER JOIN (
SELECT Min(Price) as MinP
FROM offer O
INNER JOIN (
SELECT max(OI.created) as LatestOffer, OI.Dealer_ID, OI.Product_ID
FROM Offer OI
LEFT JOIN invalids I
on OI.Id = I.offer_Id
WHERE I.ID is null
GROUP BY OI.Dealer_Id, OI.Product_Id
) B
on O.Dealer_Id = B.Dealer_Id
and O.Product_Id = B.Product_Id
and O.Created = B.LatestOffer
) Z
on OO.Price = Z.MinP
INNER JOIN product P
on P.ID = OO.Product_ID
SQL FIDDLE