Simple ordering in sql - mysql

I have table with the following data
id | name | passed | rank | Class
1 abc y 1 1
2 xyz y 1 2
3 lmn n 54 1
4 opq n 54 2
5 rst y 2 1
6 uvw y 2 2
What sql query can give me the following result:
id | name | passed | rank | Class
1 abc y 1 1
2 rst y 2 1
4 def y 55 1
3 lmn n 54 1
5 xyz y 1 2
6 uvw y 2 2
7 opq n 54 2
Group by class first all students with class = 1 , then 2 and so on.
the passsed == n should always come by the end and if there are 2 students with passed == n they should be ordered rank wise.
rest of the students with passed == y should be orders rank wise.
Tried:
select id, name, passed, rank, class
from students
ORDER BY passed DESC, rank
This gives :
id | name | passed | rank | Class
1 abc y 1 1
4 xyz y 1 2
2 rst y 2 1
5 uvw y 2 2
3 def y 55 1
6 opq n 54 2
3 lmn n 54 1
So I get passed==n at bottom and rest ordered as per rank.I think the only thing remaining is group by class.

Can't you just add the order or class first?
select id,
name,
passed,
rank,
class
from students
ORDER BY `Class`,
passed DESC,
rank

Related

can rank count duplicate value as a specific value in dax?

my table in tabular model in like below:
Id Name Score
1 mark 20
2 john 10
3 jack 20
4 Jess 20
5 Brad 9
If I use rankx it rank my table as:
Id Name Score Rank
1 mark 20 1
2 john 10 4
3 jack 20 1
4 Jess 20 1
5 Brad 9 5
is there anyway can I have the column rank as below:
Id Name Score Rank
1 mark 20 1
2 john 10 4
3 jack 20 2
4 Jess 20 3
5 Brad 9 5
Here are three options.
Rank1 = RankX ( 'Table', 'Table'[Score] + ( 0.1/'Table'[ID] ),, DESC )
Rank2 = RankX ( 'Table', 'Table'[Score] ,, DESC, Dense)
Rank3 = RankX ( 'Table', 'Table'[Score] ,, DESC, Skip)
In [Rank1] the [ID] value is used to break the ties.
In [Rank2] and [Rank3] the ties are not broken. The Skip or Dense parameters determine if rankvalues are skipped after a tie or not.

MySQL Relative ranking of values in one column for all occurrences of a given key

I'm looking for some basic direction on how where to start looking to try and rank rows of a common key in a query.
Imagine I have a table like this:
user_id | account_id | score
1 A 10
1 B 20
2 C 10
2 D 20
2 E 30
What I'm hoping to do is add a rank column for relative to each user_id where the highest score gets the top rank:
user_id | account_id | score | rank
1 A 10 2
1 B 20 1
2 C 10 3
2 D 20 2
2 E 30 1
Just looking for some basic direction in terms of which way to head :/
You can use subquery
select
*,
(select count(1)+1 from your_table b where a.user_id=b.user_id and a.score<b.score) as rank
from your_table a
Output
1 A 10 2
1 B 20 1
2 C 10 3
2 D 20 2
2 E 30 1

Mysql rank with join table, result not true

I have 2 table name table 'hasil' and table 'kat_soal' to join and give rank on each 'KatID' field on 'hasil' table..
here is my hasil table :
HasilID KatID UserID JBenar JSalah Nilai
15 1 1000 2 1 66.66666666666666
16 3 1000 2 0 100
17 1 1001 1 2 33.33333333333333
18 3 1001 1 1 50
19 1 1002 3 0 90
20 3 1002 2 0 80
and there is my kat_soal table
KatID Kategori Lama
1 IPA 30
2 IPS 30
3 Matematika 30
4 Bahasa Indonesia 20
5 Bahasa Inggris 20
this my query generate rank:
SELECT a.KatID,a.UserID,b.Kategori,c.Nama,a.JBenar,a.JSalah,ROUND(a.Nilai,2) as Nilai,
FIND_IN_SET( a.Nilai, l.list) AS rank
from hasil a
JOIN kat_soal b
ON a.KatID = b.KatID
JOIN datauser c
ON a.UserID=c.UserID
CROSS JOIN
(SELECT GROUP_CONCAT( a2.Nilai ORDER BY a2.Nilai DESC ) as list
FROM hasil a2) l
WHERE a.KatID='1'
ORDER BY a.Nilai DESC;
my result
//FOR KatID=1
KatID UserID Kategori Nama JBenar JSalah Nilai rank
1 1002 IPA ratam 3 0 90.00 2
1 1000 IPA Tarsan 2 1 66.67 4
1 1001 IPA wisnu 1 2 33.33 6
//FOR KatID=3
3 1000 Matematika Tarsan 2 0 100.00 1
3 1002 Matematika ratam 2 0 80.00 3
3 1001 Matematika wisnu 1 1 50.00 5
My Expected Result
//FOR KatID=1
KatID UserID Kategori Nama JBenar JSalah Nilai rank
1 1002 IPA ratam 3 0 90.00 1
1 1000 IPA Tarsan 2 1 66.67 2
1 1001 IPA wisnu 1 2 33.33 3
//FOR KatID=3
3 1000 Matematika Tarsan 2 0 100.00 1
3 1002 Matematika ratam 2 0 80.00 2
3 1001 Matematika wisnu 1 1 50.00 3
anyone can help me ?
Good example to solve the issue is by looking at: http://www.fromdual.com/ranking-mysql-results .
You are making this a bit complicated: First You take the value, making the value a string, then "finding position in string".
From the example it should be completely ok if it is done as (untested):
SET #rank=0;
SELECT a.KatID,a.UserID,b.Kategori,c.Nama,a.JBenar,a.JSalah,ROUND(a.Nilai,2) as Nilai,
#rank:=#rank+1 AS rank
from hasil a
JOIN kat_soal b
ON a.KatID = b.KatID
JOIN datauser c
ON a.UserID=c.UserID
WHERE a.KatID='1'
ORDER BY rank;
EDIT: Changed ordering - You are expecting to by ordered by rank in the final.
Below is the script without using table datauser for any1 to test:
SET #rank=0;
SELECT a.KatID,a.UserID,b.Kategori,a.JBenar,a.JSalah,ROUND(a.Nilai,2) as Nilai,
#rank:=#rank+1 AS rank
from hasil a
JOIN kat_soal b
ON a.KatID = b.KatID
WHERE a.KatID='1'
ORDER BY rank;

Most recent distinct record from a joined MySQL table

I have two tables, one of a list of competition results, and one with ELO ratings (based on previous competitions).
Fetching the list of competitors for an arbitrary competition is trivial enough, but I also need to get the most recent rating value for them.
score:
id | eventid | competitorid | position
1 1 1 1
2 1 2 2
3 1 3 3
4 2 2 1
5 2 3 2
6 3 1 1
7 3 3 2
8 3 2 3
rating:
id | competitorid | rating
1 1 1600
2 2 1500
3 3 1500
4 2 1600
5 3 1590
Expected output for a query against score.eventid = 3 would be
id | competitorid | position | rating
6 1 1 1600
7 3 2 1590
8 2 3 1600
At the moment my code looks like:
SELECT score.scoreID, score.competitorID, score.position,
rating.id, rating.rating
FROM score, rating
WHERE score.competitorid = rating.competitorid
AND score.eventid = 3
ORDER BY score.position
which gives an output of
id | competitorid | position | rating.id | rating
6 1 1 1 1600
7 3 2 2 1500
7 3 2 4 1590
8 2 3 3 1500
8 2 3 5 1600
basically it's showing the data from the score table for that correct event, but giving me a row for every rating available against that competitorID unfortunately I have no idea where to build in the DISTINCT statement or how to limit it to the most recent result.
MySQL noob, and managed DISTINCT statements, but not with joins. Unfortunately most previous questions seemed to deal with getting distinct results from a single table, which is not quite what I'm after. Thanks!
One way to get the rating is with a correlated subquery:
SELECT s.scoreID, s.eventID, s.competitorID, s.position,
(select r.rating
from rating r
where s.competitorID = r.competitorID
order by r.id desc
limit 1
) as rating
FROM score s
WHERE s.eventID = 3
ORDER BY s.position;
I'm not sure what ratingprid is, so this only includes the rating.

Select min/max from multiple items

I'll try to explain it as simple as possible:
First some database structure with dummy data.
Structure
tb_spec_fk
feature value
-----------------
1 1
1 2
1 3
1 4
1 5
2 2
2 3
3 1
3 4
4 2
4 3
4 4
5 1
5 3
5 5
6 3
6 5
tb_spec_feature
feature_id filter
------------------
1 2
2 2
3 2
4 2
5 1
6 0
tb_spec_value
value_id name
----------------
1 10
2 20
3 30
4 40
5 50
Now, what I want is the follow result
Result
feature_id min_value max_value
---------------------------------
1 10 50
2 20 30
3 10 40
4 20 40
But how?
Logic
Get from the tb_spec_feature where "filter" equals 2 the highest and lowest values which are present in the tb_spec_value table and connected together trough the tb_spec_fk table.
My attemps
A lot! But I'll spare you :)
SELECT
f.feature_id AS feature_id,
MAX(value.name) AS max_value,
MIN(value.name) AS min_value
FROM tb_spec_feature AS f
JOIN tb_spec_fk AS fk ON f.feature_id=fk.feature
JOIN tb_spec_value AS value ON fk.value=value.id
WHERE f.filter=2
GROUP BY f.feature_id
The two JOIN statements "link" the a feature to a value. GROUP BY groups all rows with the same feature id, and then you can take the min or max or any other aggregate function on those columns.
Demo
Here is how you can do it
select
tsf.feature_id,
tsvl.name as Min_Value,
tsvr.name as Max_Value
from tb_spec_feature as tsf
inner join (select feature , MIN(value) MinV,MAX(value)MaxV from tb_spec_fk group by feature order by feature)as tsfkl on tsfkl.feature = tsf.feature_id
left join tb_spec_value as tsvl on tsvl.value_id = tsfkl.MinV
left join tb_spec_value as tsvr on tsvr.value_id = tsfkl.MaxV
where tsf.filter = 2
group by tsf.feature_id
Output
feature_id | Min_Value | Max_Value
---------------------------------
1 | 10 | 50
2 | 20 | 30
3 | 10 | 40
4 | 20 | 40
Fiddle Demo