Joining table in mysql - 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

Related

How to neglect duplicate value in MySQL?

I have a table where I am having duplicates value also.
From that table, I want to count duplicate value as 1.
I am using below query to find count
SELECT id, team, count(*) as votes FROM vot GROUP BY team ORDER BY votes DESC;
From this query, I get the duplicates count also.
I hope I made my query clear.
I am very new to MySQL.
What I got from your question is:
Instead of --
id team votes
1 A 2
3 C 2
2 B 1
you want --
id team votes
1 A 1
2 B 1
3 C 1
For this result use the following query:
SELECT id, team, count(distinct team) as votes FROM vot GROUP BY team,id ORDER BY votes DESC;

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;

Advanced mysql query which sort down specific records on result set irrespective of its default sorting?

I have a query which actually have a sorting using order by clause. i have a table like following...
user_id user_name user_age user_state user_points
1 Rakul 30 CA 56
2 Naydee 29 NY 144
3 Jeet 40 NJ 43
.....
i have following query...
select * from users where user_state = 'NY' order by user_points desc limit 50;
This gives me the list of 50 people with most points. I wanted to give least preference to few people who's id's were known. Incase if i do not have enough 50 records then those id's should come in the last in the list. I do not want the users 2 and 3 to come on top of the list even though they have higher points... those people should come on the last of the list from the query. Is there any way to push specific records to last on result set irrespective of query sorting ?
If you want to move specific records (like user_id = 2 and 3) down to the list; Then you can run below Query:
mysql> select *,IF(user_id=2 or user_id=3,0,1) as list_order from users where user_state = 'NY' order by list_order desc, user_points desc limit 50;
select * from (
select *
from users
where user_state = 'NY'
-- this order by ensures that 2 and 3 are included
order by case when user_id in (2,3) then 1 else 2 end, user_points desc
limit 50
) as top48plus2n3
-- this order by ensures that 2 and 3 are last
order by case when user_id in (2,3) then 2 else 1 end, user_points desc
Edit: changed id by user_id and corrected outside order by (sorry about that)
On the inner select:
By using this case calculation, what you do is ensuring that records with ids equal to 2 and 3 are "important" (firstly ordered in the order by). Those receive 1 while the others receive 2 as order value, only after that points are relevant.
On the outer select:
Records with ids 2 and 3 recieve 2 as order value, while the rest recieve 1. So they go last irrespective of its "default"
Here you have a reduced fiddle http://sqlfiddle.com/#!9/377c1/1

MySQL First GROUP BY, then ORDER

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

MySQL check if MAX value has duplicates

I'm running contests on my website. Every contest could have multiple entries. I want to retrieve if only the MAX value of votes has a duplicate.
The table is as follows:
contest_id entry_id votes
1 1 50
1 2 34
1 3 50
2 4 20
2 5 55
3 6 53
I just need the query to show me that contest 1 has a duplicate MAX value without additional information.
I tried this but didn't work:
SELECT MAX(votes) from contest group by contest_id having count(votes) > 1
SELECT a.contest_ID
FROM contest a
INNER JOIN
(
SELECT contest_id, MAX(votes) totalVotes
FROM contest
GROUP BY contest_id
) b ON a.contest_ID = b.contest_ID AND
a.votes = b.totalvotes
GROUP BY a.contest_ID
HAVING COUNT(*) >= 2
SQLFiddle Demo
This finds the max votes value per contest and counts the entries with that number of votes.
It then displays contest with more than one hit.
SELECT contest_id
FROM contests
WHERE votes=(
SELECT MAX(votes) FROM contests c WHERE c.contest_id=contests.contest_id
)
GROUP BY contest_id
HAVING COUNT(*) > 1;
SQLfiddle for testing.
You could do it by first selecting the maximum number of votes for each contest ID in a subquery, and then joining against the results (demo on SQLFiddle):
SELECT contest_id, votes
FROM contest
JOIN (
SELECT contest_id, MAX(votes) AS votes
FROM contest GROUP BY contest_id
) AS foo USING (contest_id, votes)
GROUP BY contest_id
HAVING COUNT(*) > 1
The nice thing about doing it like this is that it's an independent subquery, so MySQL only needs to rub it once.
Ps. Yes, this is basically identical to JW's answer, but I figured I'd leave it up anyway to show the slightly different syntax I used for the join.