MySQL First GROUP BY, then ORDER - mysql

I've been searching all over, but couldn't come up with a proper solution to sort my table 'shop'.
This is how it looks:
Product Price
---------------------------------
Site 1 35
Site 2 50
Site 3 15
Site 1 30
Site 2 5
Now I need it to look like this:
Product Price
---------------------------------
Site 2 50
Site 2 5
Site 1 35
Site 1 30
Site 3 15
The table should be sorted starting with the highest price and then grouping it by the product.
I tried a million different queries and the closest I got was this:
SELECT m.* FROM shop m
INNER JOIN
(SELECT product, MAX(price) AS maxprice FROM shop GROUP BY product ORDER BY maxprice ASC) s
ON m.product = s.product
ORDER BY s.maxprice DESC
The query does it's job but sorts the prices in the group the wrong way around.
Product Price
---------------------------------
Site 2 5
Site 2 50
Site 1 30
Site 1 35
Site 3 15
What am I doing wrong? Help is much appreciated!
Best and thanks a million!

Select x.product, x.price from
(Select product, max(price) as mprice from shop
group by product) as tbl inner join shop x on tbl.product = x.product
order by tbl.mprice desc, x.Price desc
I also notice you created a fiddle would have saved me some time but here is the update fiddle
SELECT s.product, s.Price
from (Select product, max(price) as mprice
from shop group by product) as tbl
inner join shop s on s.product = tbl.product
order by tbl.mprice desc, s.price desc
http://sqlfiddle.com/#!2/c5eb64/3

You've got two levels of sorting, so you need to describe both in your ORDER BY
ORDER BY s.maxprice DESC, m.price DESC

Related

Find customers with similar tastes while excluding certain customers

I have a table documenting purchases from customers, with one row per purchase:
CustomerID | ProductID
1 | 1000
1 | 2000
1 | 3000
2 | 1000
3 | 1000
3 | 3000
... | ...
I am using the following code to find the ten customers with the greatest number of overlapping products with customer #1 (first result is the one with the most overlap etc):
SELECT othercustomers.CustomerID, COUNT(DISTINCT othercustomers.ProductID)
FROM `purchases` AS thiscustomer
JOIN `purchases` AS othercustomers ON
thiscustomer.CustomerID != othercustomers.CustomerID
AND thiscustomer.ProductID = othercustomers.ProductID
WHERE thiscustomer.CustomerID = '1'
GROUP BY othercustomers.CustomerID
ORDER BY COUNT(DISTINCT othercustomers.ProductID) DESC
LIMIT 10
The code yields the expected output (Customer ID + total number of overlapping products with customer #1).
I would now like the query to exclude customers with overlapping purchases who have purchased more than 1000 different products, because these are bulk buyers who purchase the entire stock and whose purchase history therefore has no meaning when searching for customers with a similar taste.
In other words, if customer #500 had bought >1000 different products, I want him/her excluded from the results when searching for customers with a similar taste to that of customer #1 - even if customer #500 has bought all three products that customer #1 had bought and would ordinarily rank first in similarity/overlap.
I suppose some HAVING is in order, but I cannot seem to figure out what the appropriate condition is.
Thanks!
I think that HAVING won't do what you want, since it will only give you the total count of overlaping products, while you want the total count of products for the other customer.
You could filter with a correlated subquery in the WHERE clause:
SELECT othercustomers.CustomerID, COUNT(DISTINCT othercustomers.ProductID)
FROM `purchases` AS thiscustomer
JOIN `purchases` AS othercustomers ON
thiscustomer.CustomerID != othercustomers.CustomerID
AND thiscustomer.ProductID = othercustomers.ProductID
WHERE
thiscustomer.CustomerID = '1'
AND (
SELECT COUNT(DISTINCT ProductID)
FROM `purchases` AS p
WHERE p.CustomerID = othercustomers.CustomerID
) < 1000
GROUP BY othercustomers.CustomerID
ORDER BY COUNT(DISTINCT othercustomers.ProductID) DESC
LIMIT 10
For performance, you want an index on purchases(CustomerID, ProductID).

MySQL Count and SUM from second table with group by

I'm trying to get sales and quantity sale by crossing two tables, group by the first one and sum from the second one.
First table has sales/operations: id_sales, sales_rep
Second table has sales details: id_sales_details, id_sales, quantity
What I need to know is how many operations had each sales_rep and what was the total quantity sum of all those sales.
This MySQL query gives me the first part:
SELECT sales.sales_rep, count(*) AS sales
from sales
Group by sales_rep
Order by sales DESC
What I cannot solve is how to add to that query the second part I need. The result should look something like:
sales_rep sales quantity
Claire 4 13
Peter 2 18
Mary 1 8
John 1 7
Here's a Fiddle to make things clearer: http://sqlfiddle.com/#!9/708234/5
SELECT s.sales_rep, count(*) AS operations, sum(d.quantity)
from sales s, sales_details d
where s.id_sales = d.id_sales
Group by s.sales_rep
Order by operations DESC;
Quick solution
SELECT w.sales_rep, w.sales, SUM(quantity) as quantity
FROM
(SELECT s.sales_rep, t.sales,d.quantity FROM sales AS s
INNER JOIN sales_details AS d ON s.id_sales = d.id_sales
INNER JOIN
(SELECT sales_rep, count(*) AS sales
from sales
Group by sales_rep
Order by sales DESC ) AS t
ON s.sales_rep = t.sales_rep) AS w
GROUP BY w.sales_rep, w.sales
ORDER BY w.sales_rep ASC

Joining table in mysql

I am developing a business review system.
business table is-
id category
1 1
2 1
3 1
4 2
review table is -
id bid reviewer_point
1 1 4
2 1 3
3 2 4
4 2 5
I need to return the 10 business ID's of the top rated (based on rating point average) business filtered by category.
So far i could find the average of the rating of each business.
SELECT business.category, bid,
COUNT(*) AS review_count, AVG(reviewer_point) AS average_points
FROM reviews
GROUP BY bid
ORDER BY average_points DESC WHERE category = 1 LIMIT 10;
I am unable to use WHERE clause. How can i get my preferred solution. Thanks in advance
The order in a mysql single query is:
1st SELECT;
2nd FROM;
3rd WHERE;
4th GROUP BY;
5th HAVING;
6th ORDER BY;
7th LIMIT.
Try put each with a break line.
The WHERE clause has to come before the GROUP BY
SELECT business.category, bid,
COUNT(*) AS review_count, AVG(reviewer_point) AS average_points
FROM review
WHERE category = 1
GROUP BY bid
ORDER BY average_points DESC
LIMIT 10;
However, this still won't work as the business table hasn't been joined in this query. I'd include this but there's no obvious way to join business to review. Should the review table have a column containing a reference to business.id?
SQLFiddle here
Best of luck.
EDIT
With the information supplied in a comment (below) by OP the revised query becomes
SELECT b.category, r.bid,
COUNT(*) AS review_count, AVG(reviewer_point) AS average_points
FROM review r
INNER JOIN business b
ON b.id = r.bid
WHERE b.category = 1
GROUP BY r.bid, b.category
ORDER BY average_points DESC
LIMIT 10;
and the updated SQLFiddle can be found here

Joining two tables and find 10 maximum averages

I am developing a business review system.
business table is-
id category
1 1
2 1
3 1
4 2
review table is -
id bid reviewer_point
1 1 4
2 1 3
3 2 4
4 2 5
I need to return the 10 business ID's of the top rated (based on rating point average) business.
So far i could find the average of the rating of each business.
SELECT COUNT(reviewer_point) AS COUNT, AVG(reviewer_point) AS average FROM reviews WHERE bid = 1
How can i get my preferred solution. Thanks in advance
Just order by the average descending and use a LIMIT clause
SELECT bid, AVG(reviewer_point) AS average
FROM reviews
GROUP BY bid
ORDER BY average DESC
LIMIT 10
EDIT - If you want to only do this for a specific category:-
SELECT reviews.bid, AVG(reviews.reviewer_point) AS average
FROM reviews
INNER JOIN categories
ON reviews.bid = categories.id
WHERE categories.category = 1
GROUP BY reviews.bid
ORDER BY average DESC
LIMIT 10
It doesn't seem like category is needed in your solution, unless I'm missing something.
Its going to be something like:
SELECT bid, COUNT(*) as review_count, AVG(reviewer_point) as average_points
FROM reviews
GROUP BY bid
ORDER BY average_points DESC
LIMIT 10;

which customer number(numbers) occur max time in a table

I have a table ORDERS which has something like this value ,
customerNumber | orderNumber(PK)
40 1
30 2
40 3
20 4
30 5
So, this table has customerNumbers 40 and 30 placing the max orders. Can anyone tell me a MySQL query to return the customerNumber (numbers), i dont want the count of the orders, just want the customer (cutomers) with the max order placed .
Thanks.
You can use below statement to get the Customer who placed maximum orders.
SELECT customerNumber FROM orders
GROUP BY customerNumber
ORDER BY COUNT(orderNumber) DESC LIMIT 1;
I should get deservedly flamed for this, but hey, the sun's out and it's feeling like a good day...
SELECT x.customernumber
FROM
( SELECT customernumber
, COUNT(*) total
FROM my_table
GROUP
BY customernumber
) x
JOIN
( SELECT COUNT(*) total
FROM my_table
GROUP
BY customernumber
ORDER
BY total DESC
LIMIT 1
) y
ON y.total = x.total;