MySQL - select multiple maximum values - mysql

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)

Related

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;

How to select * from table when group by?

select
OrderNo,
Sum(QtyIn) as QuantityIn,
Sum(QtyOut) as QuantityOut
from
tbl_Assign
group by
OrderNo
I want to select * from table also group by from table. How to do it?
To group by on all columns with a sum you cannot use *, you have to list all of the columns out and every column that isn't a function like Sum must be included in the group by.
So if you have other fields in your database such as OrderName, OrderedBy you can perform a group by like this:
Select
OrderNo,
OrderName,
OrderBy,
Sum(QtyIn) as QuantityIn,
Sum(QtyOut) as QuantityOut
From
tbl_Assign
Group By
OrderNo, OrderName, OrderBy
The following will create one row for every row in the tbl_Assign.
Each row will also show the summary information for the order.
This might not be what you need, but it's useful to understand it anyway.
SELECT T1.*, T2.*
FROM
( select * FROM tbl_Assign ) AS T1
LEFT JOIN ( select
OrderNo,
Sum(QtyIn) as QuantityIn,
Sum(QtyOut) as QuantityOut
from
tbl_Assign
group by
OrderNo
) AS T2
ON T1.OrderNo = T2.OrderNo
Harvey

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

SQL - Does row match max of sums

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

Optimize Group by & Order by query

This is structure of product table.
Currently have more 1 million records.
I have performance issue when I use query group by & order by.
Query:
SELECT product_name FROM vs_product GROUP BY store_id ORDER BY id DESC LIMIT 2
How to improve this query to perform faster? I indexed the store_id, ID is primary key.
SELECT x.*
FROM my_table x
JOIN (SELECT store_id, MAX(id) max_id FROM my_table GROUP BY store_id) y
ON y.store_id = x.store_id
AND y.max_id = x.id
ORDER
BY store_id DESC LIMIT 2;
A hacky (but fast) solution:
SELECT product_name
FROM (
SELECT id
FROM vs_product
GROUP BY store_id DESC
LIMIT 2) as ids
JOIN vs_product USING (id);
How it works:
Your index on store_id stores (store_id, id) pairs in ascending order. GROUP BY DESC will make MySQL read the index in reverse order, that is the subquery will fetch the maximum ids for each store_id. Then you just join them back to the whole table to fetch product names.
Take notice, that the query will fetch two product names for the store ids with the maximum values.
You want a query like this:
select p.*
from product p join
(select store_id, max(id) as maxid
from product p
group by store_id
) psum
on psum.store_id = p.store_id and p.id = maxid
You don't have date in any of the tables, so I'm assuming the largest id is the most recent.