I need to place set #rank:=0; in this query, but where can i place it?
SELECT #rank:=#rank+1 AS rank, p.* FROM points p
inner join distributor d
on p.distributor_id=d.id_distributor
where p.month='$prev_month'
and d.group='$dist_group'
ORDER BY p.tot_point DESC
i have to use mysql_query("set #rank:=0;"); before the main query, it's works. but in another server it won't work.
any ideas ?
SELECT #rank:=#rank+1 AS rank, p.* FROM points p, (SELECT #rank:=0) AS dummy
inner join distributor d
on p.distributor_id=d.id_distributor
where p.month='$prev_month'
and d.group='$dist_group'
ORDER BY p.tot_point DESC
Basicly just add , (SELECT #rank:=0) AS dummy after FROM points p.
My prefered layout on this query:
SELECT #rank := #rank + 1 AS rank, p.*
FROM
points AS p
CROSS JOIN
(SELECT #rank:=0) AS dummy
INNER JOIN
distributor AS d
ON p.distributor_id = d.id_distributor
WHERE p.month = '$prev_month'
AND d.group='$dist_group'
ORDER BY p.tot_point DESC ;
Related
I'm trying to rank with the left outer join
My sql is :
SET #rank=0;
SELECT #rank:=#rank+1 AS rank, h.name, COUNT(v.hId) AS votes
FROM users h LEFT OUTER JOIN users_votes v ON h.id = v.hId GROUP BY h.id
ORDER BY rank ASC
;
The right thing would be to return like this
rank | name | votes
1 Luck 4
2 Marc 3
3 Santos 2
4 Matheus 0
But it's returning the wrong way:
rank | name | votes
1 Santos 2
2 Marc 3
3 Luck 4
4 Matheus 0
You are ordering in ASC way, change it to DESC. Like this:
SET #rank=0;
SELECT #rank:=#rank+1 AS rank, h.name, COUNT(v.hId) AS votes
FROM users h LEFT OUTER JOIN users_votes v ON h.id = v.hId GROUP BY h.id
ORDER BY rank DESC
;
In MySQL 8+, you should use row_number():
SELECT ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) as rank,
h.name, COUNT(*) AS votes
FROM users h LEFT OUTER JOIN
users_votes v
ON h.id = v.hId
GROUP BY h.id
ORDER BY rank ASC;
Variables are deprecated in 8+.
In earlier version, you can use variables, but they tend not to respect ORDER BY or GROUP BY. So, with those constructs, you need a subquery:
SELECT (#rn := #rn + 1) as rank, hv.*
FROM (SELECT h.name, COUNT(*) AS votes
FROM users h LEFT OUTER JOIN
users_votes v
ON h.id = v.hId
GROUP BY h.id
ORDER BY rank ASC
) hv CROSS JOIN
(SELECT #rn := 0) params;
Doesn't works, the rank number is wrong. I want to sort by votes and rank the most voted
This question already has answers here:
Rank function in MySQL
(13 answers)
Closed 4 years ago.
SELECT u.user_id, u.user_uid, s.ostats, s.attack, s.defense
FROM stats s JOIN
users u
ON s.id = u.user_id
ORDER BY s.ostats DESC;
So in above data, "ostats"(overall) is just a sum of attack+defense and by using this query I could display users in descending order of their "ostats" values..
But how do I assign and display rank of each user, like the one with most "ostats" valued user as Rank 1 and the second highest "ostats" valued user as Rank 2 and so on..?
What about using a variable to keep track of the row number?
SET #rank = 0;
SELECT
u.user_id,
u.user_uid,
s.ostats,
s.attack,
s.defense,
(#rank:=#rank + 1) AS rank
FROM stats s
JOIN users u on s.id = u.user_id
ORDER BY s.ostats DESC;
You can assign a row number using variables:
SELECT u.user_id,u.user_uid, s.ostats, s.attack, s.defense,
s.ranking
FROM (SELECT s.*, (#rn := #rn + 1) as ranking
FROM (SELECT s.* FROM stats s ORDER BY s.ostats DESC) s CROSS JOIN
(SELECT #rn := 0) params
) s JOIN
users u
ON s.id = u.user_id
ORDER BY s.ostats DESC;
In the event of ties, this will give different users different rankings. If that is an issue, you can use this modified form:
SELECT u.user_id,u.user_uid, s.ostats, s.attack, s.defense,
s.ranking
FROM (SELECT s.*,
(#rn := if(#o = ostats, #rn,
if(#o := ostats, #rn + 1, #rn + 1)
)
) as ranking
FROM (SELECT s.* FROM stats s ORDER BY s.ostats DESC) s CROSS JOIN
(SELECT #rn := 0, #o := -1) params
) s JOIN
users u
ON s.id = u.user_id
ORDER BY s.ostats DESC;
Of course, in MySQL 8.0, you can use row_number(), rank() or dense_rank() for this purpose.
I Hope someone could help me.
My Query.
SELECT * FROM `tbl_device`
INNER JOIN `tbl_temperature` ON tbl_device.ID = tbl_temperature.DevID
Result.
How can get something like this as shown in the photo on the link.
I need to get only the last 3 result of the tbl_device.DevID
I apologize for my bad english, it's really hard to explain. Any help is realy much appreciated.
Thanks a lot!
It should be something like
SELECT * FROM `tbl_device`
INNER JOIN `tbl_temperature` ON tbl_device.ID = tbl_temperature.DevID
ORDER BY tbl_temperature.DevID DESC
LIMIT 3 OFFSET 0
The order column can be not the same as in my example. Google MySQL LIMIT OFFSET
Or if you need to get only three last results from one of your tables then join it to another then it will be something like
SELECT * FROM tbl_device INNER JOIN
(SELECT .... FROM other_table ORDER BY your_column DESC LIMIT 3 OFFSET 0) as
T1 ON T1.id = tbl_device.ID
The simplest way is to use ANSI-standard window functions (row_number() in particular). But MySQL does not support those (yet).
In MySQL, probably the best way is to use variables:
SELECT . . .
FROM tbl_device d JOIN
(SELECT t.*,
(#rn := if(#d = t.devid, #rn + 1,
if(#d := t.devid, 1, 1)
)
) as rn
FROM (SELECT t.*
FROM tbl_temperature t
ORDER BY DevID, id DESC
) t CROSS JOIN
(SELECT #d := -1, #rn := 0) params
) t
ON tbl_device.ID = tbl_temperature.DevID
WHERE rn <= 3;
EDIT:
Here is a simpler way to express the logic. It might be performant with the right indexes:
SELECT d.*, t.*
FROM tbl_device d INNER JOIN
tbl_temperature t
ON d.ID = t.DevID
WHERE t.ID >= (SELECT t2.ID
FROM tbl_temperature t2
WHERE t2.DevId = t.DevId
ORDER BY t2.ID DESC
OFFSET 2 LIMIT 1
);
For performance, this can use an index on tbl_temperature(devid, id).
This code create's rank on the fly and set's them accordingly.. Now the question is how do I update the Rank values in the table, without duplicating?I have posted this question recently but didn't find the solution.I am applying this code to a PHP code so that the rank updates with respect to TeamPoints ...
Help me Please! Thanks ...
SELECT TeamID,
TeamName,
TeamLeader,
TeamEmail,
TeamWins,
TeamLoss,
TeamPoints,
TeamRank
FROM
(
SELECT TeamID,
TeamName,
TeamLeader,
TeamEmail,
TeamWins,
TeamLoss,
TeamPoints,
#Rank := #Rank + 1 AS TeamRank
FROM team
CROSS JOIN (SELECT #Rank:=0) Sub0
ORDER BY TeamPoints DESC
) Sub1
You are just doing a SELECT statement. In order to UPDATE it really you have to use an UPDATE statement on the original table and use that query to feed values of teamRank:
UPDATE team t
INNER JOIN(
SELECT TeamID,
TeamPoints,
#Rank := #Rank + 1 AS TeamRank
FROM team
CROSS JOIN (SELECT #Rank:=0) Sub0
ORDER BY TeamPoints DESC
) a ON a.teamID = t.teamID
SET t.teamRank = a.teamRank
I have the following query which works... but I need some changes:
SELECT
p.pid,
p.name,
GROUP_CONCAT( gC.leaguepoints ORDER BY leaguepoints DESC ) AS leaguepoints
FROM
golf_player p
LEFT JOIN
golf_card gC ON
p.pid = gC.pid
GROUP BY
p.pid
ORDER BY
p.name
DESC
What I really want is another property returned called totalleaguepoints which is a SUM of the most recent 20 league points in my table.
How do I add a limit to a group_concat?
It might be something like this?
SELECT
p.pid,
p.name,
GROUP_CONCAT( gC.leaguepoints ORDER BY leaguepoints DESC ) AS leaguepoints,
SUM(
SELECT
gC2.leaguepoints
FROM
golf_card gC2
WHERE
gC2.pid = p.pid
ORDER BY
leaguepoints
DESC
LIMIT 20
) AS totalleaguepoints
FROM
golf_player p
LEFT JOIN
golf_card gC ON
p.pid = gC.pid
GROUP BY
p.pid
ORDER BY
p.name
DESC
P.S, the above query does not run
Do you want just the top 20 league points for each player in the group_concat as well as the sum?
If so maybe use user variables:-
SELECT
p.pid,
p.name,
GROUP_CONCAT( gC.leaguepoints ORDER BY leaguepoints DESC ) AS leaguepoints,
SUM(gC.leaguepoints) AS totalleaguepoints
FROM golf_player p
LEFT JOIN
(
SELECT pid, leaguepoints, #Sequence:=IF(#PrevPid = pid, #Sequence + 1, 0) AS aSequence, #PrevPid := pid
FROM
(
SELECT pid, leaguepoints
FROM golf_card
ORDER BY pid, leaguepoints DESC
) Sub1
CROSS JOIN (SELECT #PrevPid := 0, #Sequence := 0) Sub2
) gC
ON p.pid = gC.pid AND aSequence < 20
GROUP BY p.pid
ORDER BY p.name DESC