Ranking Leaderboard using MYSQL Query - php

i am having a problem, i am not that good in logic, so i am trying to do this by just using queries only,
i have a list of data, where i need to get their ranking, but the problem is, i need to get the first two upper to me and the last two who is lower to me.
for example
id| name | score
1 bob 20
2 anna 10
3 jose 30
4 boni 30
5 lea 100
6 leo 10
7 qwertina 90
8 josh 50
9 king 40
10 queen 10
imagine that my id value as a user is 7
so if i log in and my id is 7
i need to get the output of
id| name | score
5 lea 100
6 leo 10
7 qwertina 90
8 josh 50
9 king 40
is this possible in mysql query? any help would be really appreciated, i am really stuck with this problem.

You seem to base your logic on id's which is quite strange but here we are :
SELECT id, name, score
FROM yourTable
WHERE id BETWEEN yourId-2 AND yourId+2

Not sure of a MySQL only solution, but in pseudo php code
Grab records ordered by score
set a counter at 0
for loop starting 0, <= count of results
if the id your id?
if the loop index < 3 ? // there aren't two people ahead of you
return rows 0 to 4
elseif the loop index > count -3 ? // you are one of the last
return rows count -4 to count
else
return rows index -2 to index + 2 // you have 2 above and below you
Try that and if you get stuck post your PHP

Related

Need Help ranking the poll options based on prority selection

Need some help in ranking poll options, tried doing by multidimensional arrays but nothing worked.
My data structure is as per below:
**Table** Poll
**Id** **Question** **op1** p1 **op2** p2 **op3** p3 **op4** p4 **op5** p5
1 q1 ? Excellent 5 Better 4 Good 3 Ok 2 Not OK 1
2 q2 ? Sure 5 Perfect 4 Fine 3 Never 2 No 1
**Table** Answer
**id** **poll_id** **users_id** **answer** **resultOrder**
---------------------------------------------------------------
1 1 1 Excellent 1
2 1 1 Better 2
3 1 1 Ok 3
4 1 1 Good 4
5 1 1 Not Ok 5
6 1 2 Excellent 1
7 1 2 Ok 2
8 1 2 Better 3
9 1 2 Not Ok 4
10 1 2 Good 5
Each user will submit five options priorities them as per his suggestion
Option will get ranking as per counts
e.g Excellent selected for 2 times for first preference it will get 100 points and others will get 80,60,40,20 points based on their counts for all priorities.
if count ties matches points will be given on p1, p2 column in table poll
**For Example if my group by [answer] look like below 5 people voted Excellent as first preference, 4 people voted better as second preference and so on till Not Ok preferred by 1 person for fifth preference **
Answer count(answer) it should set point like this
Excellent 5 100
Better 4 80
Good 3 60
Ok 2 40
Not Ok 1 20
Hope this is possible. I tried it many ways, but no luck.

mysql php sort by highest of 3 separate fields

I've got a table with 3 separate scores in 3 separate fields:
User / Score 1 / Score 2 / Score 3
Person 1: 10 21 7
Person 2: 17 4 20
Person 3: 1 5 22
Is there a mysql command that will effectively sort each person out by the highest score from the 3 fields.
So here I need it to return:
Person 3: 1 5 22
Person 1: 10 21 8
Person 2: 17 4 20
The only way I can think of doing it would be to put them in an array, check each number for each person against each other to find the highest, then sort them into a different array.
This seems very long-winded and labour intensive though.
Add order by greatest(score1,score2,score3) desc
Manual for GREATEST()

MySQL QUERY - loop through table and perform calculations with conditions (for PHP)

I'm working on one project and now I'm in blind spot, trying to resolve this..
I have MySQL table with name x_world with some columns. Here is an example:
internalid name population date
1 John 100 2014-05-01
2 Tommy 250 2014-05-01
3 Paul 200 2014-05-01
4 Holly 700 2014-05-01
5 John 100 2014-05-02
6 Tommy 240 2014-05-02
7 Paul 201 2014-05-02
8 Holly 680 2014-05-02
9 John 100 2014-05-03
10 Tommy 230 2014-05-03
11 Paul 202 2014-05-03
12 Holly 799 2014-05-03
What i need, is get this result:
name population (+-1d) (+-3d)
John 100 0 0
Tommy 230 -10 -20
Paul 202 +1 +2
Here is explanation about what i mean and need:
Max allowed population change (grow) is 2 (including 2). If population grows over 2, dont display this row in result.
If population is only descending (no matter how much), it's okay, display this row.
Combination of both above conditions: if population descends one day (no matter how much), and then grows (no more then 2) - it's okay too, display this row.
If population does not change during these 3 days, it's okay, display this row.
In addition:
The value of population displayed in result equals to the last known value (latest date).
The two values (+-1d) and (+-3d) are calculated.
I'm beginner in PHP and MySQL. I'm familiar to very basics of both, however, the MySQL part looks insane for me :( I appreciate every piece of help. And finally, sorry for my bad english. I did my best :)
SELECT cur.name, cur.population,
cur.population-d1.population AS `+-1d`, cur.population-d3.population AS `+-3d`
FROM (
SELECT name, MAX(date) AS curdate
FROM x_world
GROUP BY name) AS maxes
JOIN x_world AS cur ON cur.name = maxes.name AND cur.date = maxes.curdate
JOIN x_world AS d1 ON d1.name = maxes.name AND d1.date = DATE_SUB(maxes.curdate, INTERVAL 1 DAY)
JOIN x_world AS d3 ON d3.name = maxes.name AND d3.date = DATE_SUB(maxes.curdate, INTERVAL 2 DAY)
HAVING `+-1d` <= 2 AND `+-3d` <= 2
DEMO
Note that although you call it +-3d, there's actually only 2 days between 2014-05-01 and 2014-05-03. I've kept your naming, but use INTERVAL 2 DAY in the calculation.

SQL - Filtering search results

OK – need some help here – might have bitten off more than I can chew here – but I’m looking to write a SQL query that always returns a minimum of 10 results. If the first condition is applied and the result set exceeds 10 results then move on to the next condition etc..
Example
Find all the small red plastic toy cars that cost less than £5.00.
I always want to show a minimum of 10 items on the screen. Want to search on “small” then on “red” and then on “< £5.00”. If the query returns more than 10 items then continue to filter on as many tags as possible (i.e plastic, toy and car) – the more matches it can make the higher it should be ranked (i.e if a products has all 3 tags associated with it – it will be at the top of the list, if a product only matches 1 tag – then this will be lower down the list.
Price Table
ID Price
1 £1.50
2 £2.50
3 £6.00
.
Colour Table
ID Colour
1 Red
2 Blue
3 Yellow
.
Size Table
ID Shape
1 Small
2 Medium
3 Large
.
Products Table
ID Description price_id colour_id size_id
1 Item 1 1 2 2
2 Item 2 2 2 1
3 Item 3 1 1 1
4 Item 4 3 2 3
5 Item 5 3 1 2
6 Item 6 1 1 2
7 Item 7 1 1 3
.
Tags Table
ID Description
1 Shiny
2 Plastic
3 Wood
4 Toy
5 Disney
6 Animal
7 Car
.
Items_Tags Table
ID tag_id product_id
1 1 1
2 4 1
3 7 1
4 2 2
5 3 3
6 4 3
7 7 6
8 7 7
9 7 2
Quite a long example - but I hope you get the point. I have wondered whether there would be any benefit to putting all the filters within the tags table - i.e the price, colour and size and then would only have to search against the tags table.
Any ideas anyone?
Thanks
It depends on your usage: filtering integers is faster than string (by the way, are they indexed?) but JOIN is also time consuming. So if the code outside the sql works with the integers, keep them (and don't join if not required to show the text)

Ordering standings football [soccer] positions by direct matches

I have a problem trying to apply rules about direct matches in a football[soccer] app. I have read this tread and it was very heplful on creating the standing positions table by the points criteria, difference and scored goals.
But i would like to know if is possible to order the teams position by direct matches:
look this positions table:
Pos Team Pld W D L F A GD Pts
1 FC Barcelona 5 2 3 0 8 5 3 9
2 **Inter Milan** 6 2 2 2 11 10 1 8
3 *Real Madrid* 6 2 2 2 8 8 0 8
4 AC Milan 5 0 3 2 8 12 -4 3
As you may see Inter Milan and Real Madrid are tied by points, and the Inter is heading real madrid because its goal difference. The result that i want to get is this :
Pos Team Pld W D L F A GD Pts
1 FC Barcelona 5 2 3 0 8 5 3 9
2 **Real Madrid** 6 2 2 2 8 8 0 8
3 *Inter Milan* 6 2 2 2 11 10 1 8
4 AC Milan 5 0 3 2 8 12 -4 3
Notice that in this time the real madrid is in front the inter milan because it won the two direct matches between them.
i have a table for teams and other for the results.
I would like to achive this using a query in mysql if is possible. Or maybe it would be better if i do this ordering on the server side (PHP).
Thanks any help would be appreciated.
It is impossible to efficiently do what you request in a single query that would return the results you ask for and sort the ties in points with that criteria.
The reasoning is simple: lets assume that you could get a column in your query that would provide or help with the kind of sorting you want. That is to say, it would order teams that are tied in points according to which one has more victories over the others (as this is very likely to happen to more than 2 teams). To make that calculation by hand you would need a double-entry table that shows the amount of matches won between those teams as follows:
| TeamA | TeamB | TeamC
------------------------------
TeamA | 0 | XAB | XAC
TeamB | XBA | 0 | XBC
TeamC | XCA | XCB | 0
So you would just add up each column row and sorting in descending order would provide you the needed data.
The problem is that you don't know which teams are tied before you actually get the data. So creating that column for the general case would mean you need to create the whole table of every team against every team (which is no small task); and then you need to add the logic to the query to only add up the columns of a team against those that are tied with it in points... for which you need the original result set (that you should be creating with the same query anyhow).
It may be possible to get that information in a single query, but it will surely be way too heavy on the DB. You're better off adding that logic in code afterwards getting the data you know you will need (getting the amount of games won by TeamA against TeamB or TeamC is not too complicated). You would still need to be careful about how you build that query and how many you run; after all, during the first few games of a league you will have lots of teams tied up against each other so getting the data will effectively be the same as building the whole double-entry table I used as an example before for all teams against all teams.
create temporary in a stored procedure and call to procedure...
create temporary table tab1 (position int not null auto_increment ,
team_name varchar(200),
points int,
goal_pt int,
primary key(position));
insert into tab1(team_name,
points,
goal_pt)
select team_name,
points,
goal_pt
from team
order by points desc,
goal_pt desc ;

Categories