mysql query - arranging rows by field and counting id x place - mysql

id field
1 100
2 80
3 200
4 230
Is it possible to find out the rank of id 2 for example if ordered by field DESC?
In this case the ranks would be:
1. #4
2. #3
3. #1
4. #2 (our winner)

If I understand your question correctly, this is what you would need. Note that since MySQL doesn't have a row numbering function, you need to use a variable in its place
SET #rank=0;
SELECT * FROM (
SELECT #rank:=#rank+1 AS rank, id, field FROM table ORDER BY field DESC
) vw
WHERE vw.id = 2;

rank is automatically in that case is created when used ORDER BY DESC. id's will keep selected in proper ranking order.
SELECT id,field FROM table_name ORDER BY id DESC

Related

Is it possible to order by two fields in a given table,one in ascending and the other in descending order at the same time?

Recently, I have come across a question that has been asked in an interview which states that:
You have mysql database with a table students. Write a query string to
select all the items of the table students and order by two fields one
ascending and the other descending.
Let's have a table "students" for example:
From this example, if we order by Score in descending order then there is no way to order by roll_no in ascending order at the same time.
From the point of view of the question, can there be written any query to obtain the desired result Or is the question ambiguous or wrong or my approach to the understanding of the question is wrong?
In your order by you have asked system to order by First column first so it have ordered then you have asked it to order by second column so it have
-> It have to keep ordering of first column.
-> Order by second column too
So it does ordering within group means if
Table Test
A| B
--------
1 1
1 3
1 2
2 2
2 4
Select * from test order by A desc, B asc
Output
Table Test
A| B
--------
2 2
2 4
1 1
1 2
1 3
So in your case, if you first order by score desc then it will order
First, all students according to there scores descending
And then if two or more students have the same score say 60 then within that group the students will be ordered according to roll number ascending
Hope this clears your doubt.
When you use the order by clause, you can specifiy the direction Asc or desc.
In your example with your sample data, there is no point of order by score, then by roll_no, because there is no duplicate in the score column.
If in your real table there are score wich appeared more than once, you can order by score desc, roll_no.
( asc is the default value)

MySQL virtually calculated column for ranking

I have a table that saves user scores in games, structured like this:
user_id (int)
game_id (int)
score (int)
I want to add another column to this table which will be a virtual column that holds the ranking of user for a game (like a table).
For example
user_id game_id score rank (virtual)
1 1 50 1
2 1 48 2
3 1 40 3
2 2 80 1
1 2 50 2
3 2 32 3
As you can see, the rank column is virtually calculated by the points in each game.
Is it even possible? And if so, what should I write in the virtuality expression field?
This doesn't account for ties, but may get you started...
SELECT x.*
, CASE WHEN #prev = game_id THEN #i:=#i+1 ELSE #i:=1 END rank
, #prev := game_id
FROM my_table
, (SELECT #prev:=null,#i:=0) vars
ORDER
BY gamed_id, score DESC;
No, it is not possible to use a generated column for calculating rank. As MySQL documentation on generated columns says:
Subqueries, parameters, variables, stored functions, and user-defined functions are not permitted.
To calculate the rank, you would have to determine the position of the record using a certain ordering within the entire table. This would require an expression that can check other records. There are no such functions within MySQL and subqueries are not allowed.
The only way to make this work is via a view, where you are allowed to use variables and subqueries to calculate the ranking.
Note, that this may change with MySQL v8.0 because it has rank() and dense_rank() functions. You have to experiment whether these functions are allowed in generated columns (I'm not sure if they are deterministic).

Learn the value in the table not by ID number

Here is a table:
5000
4900
4800
4700
3800
3600
2000
1900
1600
1000
The table does not have identification numbers.
The table is sorted by the decay, the greatest value from above.Question. How to make a mysql query to find a value of 5 on the list item? The column ID, no ...
Sorry for my bad english.
Thanks!
I am going to interpret this as finding the fifth value in the list. You can do this using limit:
select t.*
from t
order by col desc
limit 4, 1;
Do you mean you want to find a row which had value 5?
SELECT *
FROM TABLE_NAME
WHERE ID = 5
or if you mean you want the fifth element in the list,
SELECT *
FROM TABLE_NAME
LIMIT 5,1

MySql order by specific ID values

Is it possible to sort in MySQL by "order by" using a predefined set of column values (ID) like order by (ID=1,5,4,3) so I would get records 1, 5, 4, 3 in that order out?
UPDATE: Why I need this...
I want my records to change sort randomly every 5 minutes. I have a cron task to update the table to put different, random sort order in it.
There is just one problem! PAGINATION.
I will have visitors who come to my page, and I will give them the first 20 results. They will wait 6 minutes, go to page 2 and have the wrong results as the sort order has already changed.
So I thought that if I put all the IDs into a session on page 2, we get the correct records even if the sorting had already changed.
Is there any other better way to do this?
You can use ORDER BY and FIELD function.
See http://lists.mysql.com/mysql/209784
SELECT * FROM table ORDER BY FIELD(ID,1,5,4,3)
It uses Field() function, Which "Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found" according to the documentation. So actually you sort the result set by the return value of this function which is the index of the field value in the given set.
You should be able to use CASE for this:
ORDER BY CASE id
WHEN 1 THEN 1
WHEN 5 THEN 2
WHEN 4 THEN 3
WHEN 3 THEN 4
ELSE 5
END
On the official documentation for mysql about ORDER BY, someone has posted that you can use FIELD for this matter, like this:
SELECT * FROM table ORDER BY FIELD(id,1,5,4,3)
This is untested code that in theory should work.
SELECT * FROM table ORDER BY id='8' DESC, id='5' DESC, id='4' DESC, id='3' DESC
If I had 10 registries for example, this way the ID 1, 5, 4 and 3 will appears first, the others registries will appears next.
Normal exibition
1
2
3
4
5
6
7
8
9
10
With this way
8
5
4
3
1
2
6
7
9
10
There's another way to solve this. Add a separate table, something like this:
CREATE TABLE `new_order` (
`my_order` BIGINT(20) UNSIGNED NOT NULL,
`my_number` BIGINT(20) NOT NULL,
PRIMARY KEY (`my_order`),
UNIQUE KEY `my_number` (`my_number`)
) ENGINE=INNODB;
This table will now be used to define your own order mechanism.
Add your values in there:
my_order | my_number
---------+----------
1 | 1
2 | 5
3 | 4
4 | 3
...and then modify your SQL statement while joining this new table.
SELECT *
FROM your_table AS T1
INNER JOIN new_order AS T2 on T1.id = T2.my_number
WHERE ....whatever...
ORDER BY T2.my_order;
This solution is slightly more complex than other solutions, but using this you don't have to change your SELECT-statement whenever your order criteriums change - just change the data in the order table.
If you need to order a single id first in the result, use the id.
select id,name
from products
order by case when id=5 then -1 else id end
If you need to start with a sequence of multiple ids, specify a collection, similar to what you would use with an IN statement.
select id,name
from products
order by case when id in (30,20,10) then -1 else id end,id
If you want to order a single id last in the result, use the order by the case. (Eg: you want "other" option in last and all city list show in alphabetical order.)
select id,city
from city
order by case
when id = 2 then city else -1
end, city ASC
If i had 5 city for example, i want to show the city in alphabetical order with "other" option display last in the dropdown then we can use this query.
see example other are showing in my table at second id(id:2) so i am using "when id = 2" in above query.
record in DB table:
Bangalore - id:1
Other - id:2
Mumbai - id:3
Pune - id:4
Ambala - id:5
my output:
Ambala
Bangalore
Mumbai
Pune
Other
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC

specific ordering in mysql

I have a sql statement that brings back ids. Currently I am ordering the id's with the usual "ORDER BY id". What I need to be able to do is have the query order the first 3 rows by specific id's that I set. The order the remaining as it is currently. For example, I want to say the first 3 rows will be id's 7,10,3 in that order, then the rest of the rows will be ordered by the id as usual.
right now i just have a basic sql statement...
SELECT * from cards ORDER BY card_id
SELECT *
FROM cards
ORDER BY
CASE card_id WHEN 7 THEN 1 WHEN 10 THEN 2 WHEN 3 THEN 3 ELSE 4 END,
card_id
A bit shorter than Quassnoi's query, with FIELD :
-- ...
ORDER BY FIELD(card_id, 3, 10, 7) DESC
You have to invert the order because of the DESC, I didn't find a way to do it more naturally.