SQL - Does row match max of sums - mysql

I am getting a little tripped up with a SQL query. Here is some background.
Schema:
Product(pid, price, color),
Order(cid, pid, quantity),
Customer(cid, name, age)
I want to get the pid of the most ordered product (greatest quantity).
I have managed to determine the max value with:
Select Max(total)
From (Select Sum(quantity) as total
From Orders Group By pid) as Totals
but I am getting stuck trying to match which products are in this subquery. Here is what I have tried:
Select pid, SUM(quantity) as q
From Orders
Where q in (
Select Max(total)
From (Select Sum(quantity) as total
From Orders
Group By pid) as Totals
)
Group By pid
This says that q is an unknown column.
Any suggestions on how I could do this or do it better?

you can do a JOIN along with GROUP BY like
select p.*
from product p
join
(select pid from Order
group by pid having quantity = max(quantity)
) tab on p.pid = tab.pid;
In your posted query it's erroring q is an unknown column cause q is a column alias which you are trying to use in WHERE condition; which is not allowed.

You should be able to simply include the PID in the original query because you are grouping on it. Then ORDER BY and and get only the top result using LIMIT 1.
SELECT
pid
,Sum(quantity) as total
FROM
Orders
GROUP BY
pid
ORDER BY
Sum(quantity)
LIMIT 1

Here's one way you can do it using a subquery with limit:
select o.pid, sum(o.quantity)
from `order` o
group by o.pid
having sum(o.quantity) =
(
select sum(quantity)
from `order`
group by pid
order by sum(quantity) desc
limit 1
)
SQL Fiddle Demo

If you want only one most ordered product, then Karl's answer is fine. If you want all that have the same quantity, then:
select pid, sum(quantity) as quantity
from orders o
group by pid
having sum(quantity) = (select max(quantity)
from (select sum(quantity) as quantity
from orders o
group by pid
) q
);

Related

Alias table doesn't exist in where statement

The question is from https://code.dennyzhang.com/sales-analysis-i
My solution is:
select seller_id
from (select seller_id, sum(price) price
from Sales
group by seller_id) S
# where S.price = max(S.price)
where S.price = (select max(price) from S)
However, the console gives me the error message:
Table 'test.s' doesn't exist
I replaced the last line of code by
where S.price = 0
This doesn't give me any error messages meaning that S table does exist. So my question is how does this error message come from?
S is a reference to a table that can be used to qualify columns. It cannot be used in a FROM clause.
You can do what you want using a CTE:
with S as (
select seller_id, sum(price) as price
from Sales
group by seller_id
)
select seller_id
from S
where S.price = (select max(price) from S)

SQL - get several occurences for each value with DISTINCT or GROUP BY

with DISTINCT or GROUP BY a record for each value (or set of values) can be taken like in the query below:
SELECT id, MAX(price) FROM Products GROUP BY id
The result will be something like:
ID | price
1 10
2 11
Is it possible to have, for example, 3 different prices for each ID ?
You can try below - using self join
DEMO
SELECT Products.id, Products.price,COUNT(p.price) AS rank
FROM Products
LEFT JOIN Products AS p ON Products.id = p.id AND Products.price< p.price
GROUP BY Products.id, Products.price
HAVING COUNT(p.price) < 3
ORDER BY Products.id, Products.price DESC
You can use GROUP_CONCAT if you want to get all the values, e.g.:
SELECT id, GROUP_CONCAT(price)
FROM table
GROUP BY id;
If your MySql version supports Window functions you can use RANK() and PARTITION
SELECT id, price
FROM (SELECT id, price, RANK() OVER w as price_rank
FROM test
WINDOW w as (PARTITION BY id ORDER BY price desc)) r
WHERE price_rank <= 3
ORDER BY id, price desc
One way to get the three highest prices is to use group_concat() and substring_index():
SELECT id,
SUBSTRING_INDEX(GROUP_CONCAT(price ORDER BY price DESC), ',' 3) as top3_prices
FROM Products
GROUP BY id;

Mysql query to get lowest value from multiple conditions using UNION operator

I have price table with three columns:
id, price, product_id.
product_id can contain multiple prices.
I need to get lowest price product_id when query perform in mysql.
I am using multiple conditions using UNION operator in this table data is coming but results are wrong.
In this table product_id 101 has 4999 but I am getting 5000, even I have set order by price ASC
Here is my mysql fiddle link
mysql fiddle
This is very basic SQL.
select product_id, min(price) as price
from price
group by product_id;
To fetch minimum prices per product for a given range add them to case statement in group by clause:
select product_id, min(price) as price
from price
group by product_id, case when price between 100 and 5000 then 1 else 2 end;
SQL fiddle
Assuming you need the ID of each record with the min price.
Select p.* from price p
INNER JOIN (Select product_ID, Min(Price) as price from `price` group by Product_ID) sub
on sub.product_Id = p.product_Id
and sub.price = p.price
SQL FIDDLE
Otherwise...
Select product_ID, Min(Price) as price from `price` group by Product_ID
SQL FIDDLE
---- UPDATE----
Still not sure I understand the question... which is why I asked for expected output given your data. I may be able to infer the requirements which i'm not getting. As it stands I had NO idea why a union was needed, nor how this "grouping" came into play.
SELECT p.* from price p
INNER JOIN (Select product_ID, Min(Price) as price from `price` group by Product_ID) sub
on sub.product_Id = p.product_Id
and sub.price = p.price
SQL Fiddle
Assuming no overlap of product_ID in ranges...
SELECT pr.id,MIN(pr.price),pr.product_id FROM price pr WHERE pr.price >= 100 AND pr.price <= 5000 group by pr.product_id UNION SELECT pr.id,MIN(pr.price),pr.product_id FROM price pr WHERE pr.price >= 5001 AND pr.price <= 10000 group by pr.product_id

MySQL - Matching ID to Max of Count ("Need" more elegant solution)

Is there a better way to do the following:
SELECT ProductID, MAX(a.countProductID)
FROM
(
SELECT ProductID, COUNT(ProductID) as countProductID
FROM SalesOrderDetail
LEFT JOIN Product USING (ProductID)
GROUP BY ProductID
) as a
WHERE a.countProductID = (SELECT MAX(x.countProductID) FROM
(
SELECT ProductID, COUNT(ProductID) as countProductID
FROM SalesOrderDetail
LEFT JOIN Product USING (ProductID)
GROUP BY ProductID
) as x
);
Since im using the same subquery twice. However i can't access the first one from the WHERE clause.
I guess the task is to find product or products with the maximum sales count. First you shouldn't join with PRODUCT table because all information you need is in SalesOrderDetail table. Then use LIMIT 1 to find maximum count and HAVING to select all products with maximum count:
SELECT ProductID, COUNT(ProductID) as countProductID
FROM SalesOrderDetail
GROUP BY ProductID
HAVING COUNT(ProductID) = (SELECT COUNT(ProductID) as countProductID
FROM SalesOrderDetail
GROUP BY ProductID
ORDER BY countProductID DESC
LIMIT 1 )
The final answer
SELECT ProductID, COUNT(ProductID) as countProductID
FROM SalesOrderDetail
LEFT JOIN Product USING (ProductID)
GROUP BY ProductID
ORDER BY countProductID desc
LIMIT 1

MySQL - select multiple maximum values

I have a table called order which contains columns id, user_id, price. I would like to select each user's most expensive order - the order for which that user paid the highest price. I want to select order.user_id and order.price in the same query.
select user_id, max(price) from `order` group by user_id
SELECT order.user_id, A.price
FROM `order`
LEFT JOIN
(SELECT user_id, price FROM `order` ORDER BY price DESC) A USING (user_id)