I have this SQL query for getting the rank number of a team in my database based on their 'point'.
SELECT id, points, team_name, FIND_IN_SET( points, (
SELECT GROUP_CONCAT( points
ORDER BY points DESC )
FROM teams )
) AS rank
FROM teams
WHERE id = ?
LIMIT 1
The problem I'm having is that given the scenario that two teams have the same points e.g. say there is 2 teams and each team has '0' points. The query returns rank '1' for both of the teams.
I want the team with the lower 'id' to have the higher rank between the teams with the same points.
For example say team1 and team2 both have '5' points. I want the team with the lower id to have rank 1.
How can I alter my query to do that?
Thanks
The method you are using has limited applicability in MySQL, because it depends on the length of the intermediate substring in the group_concat(). However, you can modify it for this purpose:
SELECT id, points, team_name,
FIND_IN_SET(CONCAT(points, ':', id),
(SELECT GROUP_CONCAT(points, ':', id ORDER BY points DESC, id )
FROM teams
)
) AS rank
FROM teams
WHERE id = ?
LIMIT 1;
A better method is:
select id, points, team_name,
(select count(*)
from teams t2
where t2.points > t.points or
(t2.points = t.points and t2.id <= t.id)
) as rank
from teams t
where id = ?;
Related
There is a table with fields - id, student_name, score.
How do a write a mysql/php query that will get the position
of a student based on the score field.
For example if we have scores: 60,57,80,90,85; student with score 90 will
have 1st position, 85 2nd position etc.
Two scores if equal will have same position nth, but the next score will
have n+2th position.
What does the SQL query look like?
You can use rank():
select t.*, rank() over (order by score desc) as rnk
from t;
If you want this for a particular student, use a subquery:
select t.*
from (select t.*, rank() over (order by score desc) as rnk
from t
) t
where studentid = ?
I want a new rank column to show the rank; according to date for a book order of a member
Your goal is still not very clear.
But here is my approach (you should replace mem_records with your real table name):
http://sqlfiddle.com/#!9/6be133/3
SELECT t.*, t_rank.rank
FROM mem_records t
LEFT JOIN (
SELECT t_ord.*,
#rank:= IF(#rank IS NULL,1,#rank+1) `rank`
FROM (
SELECT mem_id,
MIN(`date`) rank_date
FROM mem_records
GROUP BY mem_id
ORDER BY rank_date
) t_ord
) t_rank
ON t.mem_id = t_rank.mem_id
Suppose I have a table named studens.
I want to count how many students who received duplicated scores at least 2 times.
Please help me, thanks.
The result that I expect is: Jonh have 100 score 2 times, James have 80 scores 2 times, Julia has 50 scores 2 times. So the amount of students who receive duplicated score at least 2 times is 3 (Jonh, Jam, and Julia).
select count(*) from
(
select name
from your_table
group by name, score
having count(*) > 1
) x
Based on the edit, your query would be:
select distinct name
from students
group by name, score
having count(*) > 1;
You could see the scores and counts by doing:
select name, score, count(*)
from students
group by name, score
having count(*) > 1;
By the way, the first query is one of the very, very few times where select distinct is appropriate with a group by. I think the second query provides more information, though.
Assuming a student has only one score per subject (that is, name, subject is unique):
SELECT COUNT(DISTINCT t1.name)
FROM scores t1
INNER JOIN scores t2
ON t1.name = t2.name
AND t1.subject <> t2.subject
AND t1.score = t2.score
SQLFiddle
I have a query that gets me a users rank in a table of scores.
SELECT
*
FROM
(SELECT
*, #rank:=#rank + 1 rank
FROM
(SELECT
user_id, SUM(round_total) TotalPoints
FROM
sx14sp_mem_picks
GROUP BY user_id) s, (SELECT #rank:=0) init
ORDER BY TotalPoints DESC) r
WHERE
user_id = 22234
There is a problem with ties. I have a table field "pick_date" that i would like to use to break ties with. The user who made his picks first beats the tie.
Any ideas?
If sx14sp_mem_picks.pickdate is the field to break ties then in the order by sx14sp_mem_picks subquery, add
min( pickdate) asc
This will put the earliest pickdate first - you have to use MIN() bc you need to use an aggregate function given the use of "group by".
You need to order by the pick date in addition to the total points. However, you are talking about multiple rows per user. So, let's take the last pick date:
SELECT *
FROM (SELECT *, (#rank:=#rank + 1) as rank
FROM (SELECT user_id, SUM(round_total) as TotalPoints, max(pick_date) as max_pick_date
FROM sx14sp_mem_picks
GROUP BY user_id
) s CROSS JOIN
(SELECT #rank := 0) init
ORDER BY TotalPoints DESC, max_pick_date asc
) r
WHERE user_id = 22234;
I have a table with a column called bid and I would like to list how many records there exists with each bid value.
Kind of making a TOP TEN list.
Example:
bid with value 1 has 5 entries/rows.
bid with value 2 has 3 entries/rows.
bid with value 3 has 8 entries/rows.
etc
How do I make a query that counts and sums up each of the bid's and sort the in a DESCending order?
Thankful for any kind of help!
This should work in MySQL
select u.firstname, t.bid, count(*) as counts
from your_table t
join users u on u.bid = t.bid
where t.confirmed <> '0000-00-00 00:00:00'
group by t.bid
order by counts desc
Generally you can do
select u.firstname, t.bid, t.counts
from
(
select bid, count(*) as counts
from your_table
where confirmed <> '0000-00-00 00:00:00'
group by bid
) t
join users u on u.bid = t.bid
order by t.counts desc
How about this?
SELECT bid, count(*) as TotalHits
FROM tableName
GROUP BY bid
if you want result as per hits sorted, use
SELECT bid, count(*) as TotalHits
FROM tableName
GROUP BY bid
ORDER BY TotalHits DESC