mysql get order number - mysql

I have the following structure
Country - UserId - Points
840 23 24
840 32 31
840 22 38
840 15 35
840 10 20
250 15 33
724 17 12
etc
I want to get the position of user in the ranking of each country accordin points
I'm using
select #rownum:=#rownum+1 Num, Country, UserId, points
from users , (SELECT #rownum:=0) r
where country=840 order by points DESC ;
I want to get the position of a single user inside his country
In this example, in country 840, if I select user id=23, I'll get position 4
Country - UserId - Points- Order
840 22 38 1
840 15 35 2
840 32 31 3
840 23 24 4
840 10 20 5

Try doing:
select * from (
select #rownum: = #rownum + 1 Num,
Country,
UserId,
points
from users, (select #rownum: = 0) r
where country = 840
order by points desc
) a
where userId = 23

Using your query you'll receive row number in your results so it's not what you want to. Best way is to generate positions and save them to separated column. This way you'll be able to select it easy and there will be no need to recalculate it each time (which is very important).
To do it you can modify your query to update rows instead of selecting it.

Related

How to find the smallest value in a row

i need help to create a sql query that can find the smallest value in 1 row , and display it in the last column, like this table.
id
out
mid
in
Smallest
1
200
100
50
50
2
100
150
50
50
3
200
100
250
100
4
50
100
150
50
5
50
100
100
50
6
20
200
100
20
7
-
-
100
100
8
150
-
100
100
this is my query :
On MySQL you may use the scalar LEAST() function:
SELECT id, `out`, mid, `in`, LEAST(`out`, mid, `in`) AS Smallest
FROM yourTable;
If your database doesn't have a LEAST function, we can use a CASE expression as an alternative:
SELECT id, `out`, mid, `in`,
CASE WHEN `out` < mid AND `out` < `in` THEN `out`
WHEN mid < `in` THEN mid
ELSE `in` END AS Smallest
FROM yourTable;
Side note: Both IN and OUT are reserved MySQL keywords, and you should avoid naming your columns with them.

Check duplication within the same MySQL table

id district icnum
1 10 111
2 10 112
3 10 113
4 10 114
5 10 111
6 20 115
7 20 116
8 20 117
9 20 111
10 20 111
11 30 118
12 30 119
13 30 111
14 30 111
15 30 120
I have the above sample table. I want to create a mysql query to check duplication of 'icnum', a summary/count and also a list of the duplication. What
I want is:
How many 'icnum' within district '10' is found in district '20'.
How many 'icnum' within district '10' is found in district '30'.
How many 'icnum' within district '20' is found in district '30'.
I've tried several queries found in stackoverflow but it doesn't give me the result I want. I'm a newbie in complex sql query.
So should I execute the query separately for every district to get the result. Please masters of MySQL in stackoverflow, help me with this. Tq.
Below is the sample output that i want:
district district count(*)
10 20 2
10 30 2
20 30 2
You can do this using a self-join:
select t1.district, t2.district, count(distinct t1.icnum)
from t t1 join
t t2
on t1.icnum = t2.icnum and t1.district < t2.district
group by t1.district, t2.district;
Notes:
If you don't have duplicates, then use count(*) instead of count(*).
This will not return pairs that have nothing in common (although that could be fixed).

MySQL last 50 records

I have to get the last 50 records from my MySQL database.
Here is the structure of my test database:
ID S1 S2 S3 Date-time Label
13 32 55 33 2017-09-05 13:15:06 temperature
16 111 222 66 2017-09-05 19:22:14 temperature
17 44 55 33 2017-09-05 19:22:14 temperature
18 55 11 88 2017-09-12 14:22:00 temperature
21 77 1 200 2017-09-15 12:24:06 temperature
22 22 55 11 2017-09-19 14:37:00 temperature
How could I show only the last 3 data? for example:
18 55 11 88 2017-09-12 14:22:00 temperature
21 77 1 200 2017-09-15 12:24:06 temperature
22 22 55 11 2017-09-19 14:37:00 temperature
Greetings and thank you.
In Oracle12c you can use the fetch keywork:
SELECT *
FROM table
ORDER BY id DESC
FETCH FIRST 50 ROWS ONLY;
FOR ORACLE:
SELECT * FROM (
SELECT ID,
S1,
S2,
S3,
Date-time,
Label
FROM TABLE
ORDER BY ID DESC)
WHERE ROWNUM <= 50;
FOR MYSQL:
SELECT ID,
S1,
S2,
S3,
Date-time,
Label
FROM TABLE
ORDER BY ID DESC
LIMIT 50;
Here is a quick doc:
https://www.w3schools.com/sql/sql_top.asp
Edit:
For the last 50 rows:
SELECT * FROM (
SELECT * FROM table ORDER BY id DESC LIMIT 50
) sub
ORDER BY id ASC
Use Top N Query (row num<=50) fro first, for last 50 you can use "order by id desc"
First I was confused with the Post between ORACLE and MYSQL I apologize.
The solution at the end was the following:
SELECT * FROM inv ORDER BY id DESC LIMIT 50
then transform the ARRAY that I collect with the function:
var dorde = d0.reverse ();
thanks for everything.

Select more columns with GROUP_CONCAT( ) according to lowest date

I have one table accounts. I have written following query
chk_account= mysql_query("SELECT GROUP_CONCAT( DISTINCT user_id ) AS userlist
FROM `accounts`
");
From this I get users id only. With this query I also want to fetch data price and date with column name price and created but I need only to select with lowest date
I have table structure like this:
id user_id price created
1 31 10 2013-04-09 17:30:15
2 32 20 2013-04-10 20:24:40
3 31 30 2013-04-11 04:44:25
4 33 40 2013-04-12 05:47:18
5 34 50 2013-04-13 19:54:15
6 34 50 2013-04-14 14:27:15
7 35 10 2013-04-15 13:54:45
8 35 60 2013-04-16 12:24:35
9 35 10 2013-04-17 20:34:10
I suspect that you want the earliest date and price for each user. You can do this using group_concat(), using a query such as:
select USER_ID,
substring_index(group_concat(price order by created), ',', 1) as price,
min(created)
from accounts a
group by user_id

MSSQL Select Top 10 winning scores, including Ties and at least one from each category

I got some help finding the top 10 scores, including tied entries, using the following statement
select T.EntryID, T.CategoryID, T.Score
from (
select EntryID, CategoryID, Score,
dense_rank() over(order by Score) as rn
from YourTable
) T
where T.rn <= 10
(thanks [mikael-eriksson]: https://stackoverflow.com/users/569436/mikael-eriksson)
[question]: MSSQL Selecting top 10 but include columns with duplicate values Here is sample data:
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3047 1 80
3048 1 80
3049 1 80
3193 1 80
3098 1 80
3025 1 72
3082 1 70
3167 1 70
3122 1 67
3220 1 65
3080 1 65
3168 1 64
______________________
Total Entries >= 18
There is a requirement that there be at least one entry from each category in the top 10 (or top whatever it may be i.e. top 100), in this case there are 3 Categories.
Now all I need to do is to include at least one entry per category in the top 10. i.e. if all the top 10 scores are from Category 1, and there are 3 categories, I need to drop the 2 lowest scores from Category 1 and include the highest score entry for both Category 2 and 3.
As you can see from the results all the entries are from Category 1, so I need to drop EntryID's 3220, 3080 and 3168 from the resultset as they are the lowest scored, and include the highest scoring entry in Category 2 as well as the highest scoring entry in Category 3 so that the result looks something like this:
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3047 1 80
3048 1 80
3049 1 80
3193 1 80
3098 1 80
3025 1 72
3082 1 70
3167 1 70
3122 1 67
3019 3 60
3800 2 54
______________________
Total Entries >= 17
Same thing goes for the following scenario, let's look at the top 5 instead of top 10 to make it a little easier on the eye, as you can see in this example the Top 5 scores exclude entries from Category 2
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3019 3 60
______________________
Total Entries >= 7
In this case entries 3225 and 3045 needs to drop as they are the lowest scored entries (3047 needs to be included as even though it's the lowest scored entry I need an entry from all categories in the result) and I need to include the highest scored entry from Category 2, I would expect something like this:
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3019 3 60
3800 2 54
______________________
Total Entries >= 6
And then there may be the scenario where there may not be an entry into a specific category, let say for example no Category 2 entries so the result should still have the top 5 as with the original result set for the top 5 above (included below as reference)
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3019 3 60
______________________
Total Entries >= 7
Please excuse if I'm repeating myself, I'm just trying to make it clear to understand ;)
I really Appreciate the help!
As I can see it, you need to rank your rows in a more sophisticated way, so that entries that are the top ones in every category are included regardless of their values, and entries that are not the top ones are included according to their overall rankings.
What I'm about to suggest may not be the most efficient solution, but it should work and, if nothing else can, might inspire someone else to come up with something better:
WITH ranked1 AS (
SELECT
*,
RankByCategory = DENSE_RANK() OVER (
PARTITION BY CategoryID
ORDER BY Score DESC
)
FROM YourTable
),
ranked2 AS (
SELECT
*,
FinalRank = DENSE_RANK() OVER (
ORDER BY
CASE RankByCategory WHEN 1 THEN 1 ELSE 2 END,
Score DESC
)
FROM ranked1
)
SELECT
EntryID,
CategoryID,
Score
FROM ranked2
WHERE FinalRank <= #top_n
;
The first CTE is ranking rows by categories, thus letting us find out which entries become the top ones in their respective categories. The next step (second CTE) is about obtaining global rankings, this time taking into account whether an entry is the top one in its category or not. The category top values receive lower rankings and thus are ensured to be included in the final results. (Of course, you need to make sure that the number of categories is not greater than the number of distinct values you want to receive in the output.)
Here's a live example at SQL Fiddle to play with.