I have a MySQL table like so...
ID | NAME | RANK | PTS
---+-------+------+----
12 | John | 1 | 28
18 | Andy | 2 | 31
23 | Brian | 3 | 16
41 | Mike | 4 | 33
15 | Jack | 5 | 35
68 | Anne | 6 | 24
I currently sort by...
SELECT * FROM `ranks` ORDER BY PTS desc
I am looking for some code that I can give it an ID, and it'll return it's ranking by the PTS column. For ID 41, it should return 2 as the 2nd best score of that column.
I am not sure what to google for to get an answer. Is there some SQL code that can do this simply? or maybe php? The RANK column is overall rank, and PTS is the current weekly score so far. There might be up to 2.5 million entries eventually. Please let me know if you have any questions.
// get the number of ppl w/ points higher than the given user's
SELECT count(*) + 1 FROM ranks WHERE PTS > (
SELECT PTS FROM ranks WHERE ID = 41);
...though if you are looking to scale this you probably want to reconsider how you are structuring your data.
try this query:
Step1:
CREATE TABLE t (
id INT(3),
name char(60),
score INT(5)
);
insert into t values(10,"name1",33);
insert into t values(11,"name2",43);
insert into t values(12,"name3",335);
insert into t values(13,"name4",233);
Step2:
SET #rank=0;
SELECT #rank:=#rank+1 AS rank, name, id, score from t order by score desc
You just put the PTS into an array and create a loop to add the column output.
$sum = 0;
foreach ($array as $num){
$sum = $sum + $num;
}
return $sum;
Related
In database I have such table:
| id hotel_id | room_id | Ac_rooms | Non_ac_rooms | simple_rooms | Furnitured_room | other_rooms | added_by |
| 9 | 2 | 3 | 2 | 6 | 12 | 21 | raj |
I want to get the total numbers of room from SQL query (which is the total of room_id, Ac_rooms, Non_ac_rooms, simple_rooms, Furnitured_room, other_rooms).
What is the best way to get the total from SQL query? I need total number of rows.
Try this:
SELECT
SUM(Ac_rooms) as Ac_rooms,
SUM(Non_ac_rooms) as Non_ac_rooms,
SUM(Simple_rooms) as Simple_rooms,
SUM(Furnitured_rooms) as Furnitured_room,
SUM(Other_rooms) as Other_rooms,
SUM(Ac_rooms+Non_ac_rooms+Simple_rooms+Furnitured_room+Other_rooms) as Total_rooms,
FROM tbl_rooms
Or
SELECT
SUM(SUM(Ac_rooms)+SUM(Non_ac_rooms)+SUM(Simple_rooms)+SUM(Furnitured_room)+SUM(Other_rooms)) as Total_rooms,
FROM tbl_rooms
If I understood you correctly, you just need the sum
select (ac_rooms + Non_ac_rooms + simple_rooms + Furnitured_room + other_rooms) as total_rooms from YOUR_TABLE
Also you specified finding total number of rows, which you can get by using standart count function
select count(*) as number_of_rows from YOUR_TABLE
Or may be you are looking for the sum of types of the rooms through all the rows? In that case you will need
select sum(ac_rooms ), sum(Non_ac_rooms), sum(simple_rooms), sum(Furnitured_room), sum(other_rooms) from YOUR_TABLE
UPD: If I got you right, you need this
select sum(ac_rooms ) as ac_rooms_total,
sum(Non_ac_rooms) as non_ac_rooms_total,
sum(simple_rooms) as simple_rooms_total,
sum(Furnitured_room) as furnitured_room_total,
sum(other_rooms) as other_rooms_total,
sum(ac_rooms + Non_ac_rooms + simple_rooms + Furnitured_room + other_rooms) as TOTAL
from YOUR_TABLE
I have a huge number of rows that I'd like to get say, last 5 records inserted in that database from 10 different users. If the same user inserted the last 3 rows into database, we must get one row, skip the others two and move to get a row per user, until it count up to 5.
A database like that:
user_id | news_id | title
1 | 1 | foo-1
2 | 2 | foo-2
3 | 3 | foo-3
1 | 4 | baa
4 | 5 | baa0
5 | 6 | baa1
5 | 7 | baa2
6 | 8 | baa3
7 | 9 | baa4
Should return:
user_id | news_id | title
1 | 1 | foo-1
2 | 2 | foo-2
3 | 3 | foo-3
4 | 5 | baa0
5 | 6 | baa1
The current filter was done by PHP, like this:
$used = array();
while ($data = mysql_fetch_array($query)) {
$uid = $data['user_id'];
if(in_array($uid, $used))
continue;
array_push($used, $uid);
// do something with data
}
But I want to refactor it, and do the filter purely by mysql, if possible. I don't know much MySql and that's why I'm having problem to archive this...
Here's what I've tried
select DISTINCT(user_id), news_id, title from XXX
WHERE GROUP BY (news_id) DESC
LIMIT 0,5
How can I do that?
1 way you can do it is to generate a partitioned row number per user and then select 5 records where RowNumber = 1.
SELECT *
FROM
(
SELECT
d.user_id
,d.news_id
,d.title
,(#rn:= if(#uid = user_id, #rn + 1,
if(#uid:=user_id,1,1)
)
) as RowNumber
FROM
Data d
CROSS JOIN (SELECT #uid:=-1, #rn:=0) vars
ORDER BY
user_id
,news_id
) t
WHERE
t.RowNumber = 1
ORDER BY news_id
LIMIT 5;
http://rextester.com/JRIZI7402 - example to show it working
Note you can change the row order by simply changing the ORDER BY statement of the derived table so if you have a column that will signify the latest record e.g. an identity column or a datetime column you can use that, but user_id must be the first criteria to be partitioned correctly.
Do it from your query.
"SELECT * FROM table GROUP BY user_id ORDER BY news_id DESC LIMIT 5"
well, i think this will achieve what you are after.
select user_id, news_id, title from tableName
GROUP BY user_id
ORDER BY news_id DESC
LIMIT 0,5
Hope this helps!
I have some data row in my table.
I want to select the Age which occurs the most.
Person | Group | Age
---
Bob | 1 | 32
Jill | 1 | 32
Shawn| 1 | 42
Jake | 2 | 29
Paul | 2 | 36
Laura| 2 | 39
Desired set:
The age that appears the most is 32.
Use the following query
select Person, count(*) as c FROM tableName GROUP BY Age
You can add the limit 1 to get the only only record and order by to get the maximum or minimum age. Use following query
select Person, count(*) as c,Age FROM profile GROUP BY Age ORDER BY c desc LIMIT 0,1
Try something like this
SELECT Person,Group,Age,MAX(field_name)
FROM table_name;
After grouping the values you can select the top 1 as below : This would select 32 as answer
SELECT TOP (1) Age
FROM tablename
GROUP BY age
ORDER BY COUNT(*) DESC
SELECT age FROM my_table GROUP BY age ORDER BY COUNT(*) DESC LIMIT 1;
Fairly obviously, in the case of a tie, this result will be misleading.
Assuming we have a table like below
id | name | userid | score | datestamp |
------------------------------------------------------------
1 | john | 1 | 44 | 2013-06-10 14:25:55
2 | mary | 2 | 59 | 2013-06-10 09:25:51
3 | john | 1 | 38 | 2013-06-10 21:25:15
4 | elvis | 3 | 19 | 2013-06-10 07:25:18
5 | john | 1 | 100 | 2013-06-14 07:25:18
I want to select the all time high-score of each user.
so for example if the player john have played ten rounds in 2013-06-10 and his score is 430 in total for that day. and in 2013-06-14 he plays 16 rounds and his scores is 1220 in total for that day. i want to display the the best score of user john, and so on for the others players. in the example above johns best score was 2013-06-14 with score 1220.
Detailed example:
If user John plays 3 rounds in 2013-06-10. First round he scores 44, second time he scores 38 and third time he scores 55. His total score for that day is 137. And on the next day 2013-06-11 he plays 5 rounds with a total score of 220. In this example his best total score so far is 220. So it should group all scores for each day to a total. And then compare this total with other days total and display the highest total of that user
Thanks in advance
This should do the trick:
SELECT userId, name, MAX(score) as highScore
FROM (
SELECT userID, name, SUM(score) as score, date(datestamp) as scoreDate
FROM TableName
GROUP BY userID, scoreDate
) dailyScores
GROUP BY userId
The inner query fetches the totals of each user's scores on each date (timestamp converted to date to remove time information), the outer query then gets the highest total score of each date for each user.
I took the liberty of basing on J W's fiddle, and I added another row to your example data so the functionality is obvious, try it out here:
http://www.sqlfiddle.com/#!2/f6bea/3
SELECT a.*
FROM Tablename a
INNER JOIN
(
SELECT userID, MAX(score) max_Score
FROM TableName
GROUP BY userID
) b ON a.userID = b.userID AND
a.score = b.max_Score
SQLFiddle Demo
For faster searching, you need to have compound index on (userid, score). Here's how to implement it:
ALTER TABLE TableName ADD INDEX (userid, score)
My table will hold scores and initials.
But the table wont be ordered.
I can get the total row count easy enough and I know I can get all of them and Order By and then loop through them and get the rank THAT way...
But is there a better way? Could this maybe be done with the SQL statement?
I'm not TOO concerned about performance so if the SQL statement is some crazy thing, then Ill just loop.
Sorry - Table has id as primary key, a string to verify unique app install, a column for initials and a column for score.
When someone clicks GET RANK... I want to be able to tell them that their score is 100 out of 1000 players.
SELECT s1.initials, (
SELECT COUNT(*)
FROM scores AS s2
WHERE s2.score > s1.score
)+1 AS rank
FROM scores AS s1
Do you have a primary key for the table or are you fetching data by the initials or are you just fetching all the data and looping through it to get the single record? How many results are you trying to fetch?
If you only want to fetch one record, as the title suggests, you would query the database using a WHERE conditional:
SELECT score FROM table WHERE user_id = '1';
See this answer: https://stackoverflow.com/a/8684441/125816
In short, you can do something like this:
SELECT id, (#next_rank := IF(#score <> score, 1, 0)) nr,
(#score := score) score, (#r := IF(#next_rank = 1, #r + 1, #r)) rank
FROM rank, (SELECT #r := 0) dummy1
ORDER BY score DESC;
And it will produce a result like this:
+------+----+-------+------+
| id | nr | score | rank |
+------+----+-------+------+
| 2 | 1 | 23 | 1 |
| 4 | 1 | 17 | 2 |
| 1 | 0 | 17 | 2 |
| 5 | 1 | 10 | 3 |
| 3 | 1 | 2 | 4 |
+------+----+-------+------+
Note that users with equal scores have equal ranks. :-)