How would I do this query in laravel - mysql

How can I do this in laravel query builder? (this basically gets your current position in a voting system)
SELECT position FROM
(SELECT participant.target_user_id, #rownum := #rownum + 1 as position FROM
(SELECT target_user_id, count(*) as votes FROM contest_participants_votes GROUP BY
target_user_id ORDER BY votes DESC) as participant
JOIN (SELECT #rownum := 0) r) x
WHERE target_user_id = 1

We used a raw statement like this with placeholder
$position = \DB::select(\DB::raw(
'SELECT position FROM
(SELECT participant.target_user_id, #rownum := #rownum + 1 as position FROM
(SELECT target_user_id, count(*) as votes FROM contest_participants_votes GROUP BY
target_user_id ORDER BY votes DESC) as participant
JOIN (SELECT #rownum := 0) r) x
WHERE target_user_id = ?'), [$pid]);

Related

MySQL join table to itself based on row number returns no data

I've got a logs table with an ID column in it, and I want to do the following:
Select the ID and row number
Join the table to itself based on the row number
My objective is to get a specific row as well as the row before it. The SQL query below actually returns nothing. It's like it forgets the row number entirely. Joining on ID returns just fine.
Is there something that needs to be done in MySQL to support this kind of operation?
select * from
(select id, #rownum := #rownum + 1 as 'row'
from logs, (select #rownum := 0) r order by id) a
join
(select id, #rownum := #rownum + 1 as 'row'
from logs, (select #rownum := 0) r order by id) b
on a.row = b.row;
Change your variable name in second query, using same variable in both queries can produce unexpected results
select * from
(select id, #rownum := #rownum + 1 as 'row'
from logs, (select #rownum := 0) r order by id) a
join
(select id, #rownum1 := #rownum1 + 1 as 'row1'
from logs, (select #rownum1 := 0) r order by id) b
on a.row = b.row1;

mysql find position in recordset but grab value from another table

I have this sql that grabs the wealth ranking (position) of a single player from the players recordset. But I need to do a join to the users table to ignore banned players while finding the position.
My existing code (checking for player id 5):
SELECT z.rank FROM
(SELECT p.id, p.name, #rownum := #rownum + 1 AS rank FROM players p, (SELECT #rownum := 0) r
WHERE p.this != 'that' ORDER BY p.cash + p.bank DESC) as z #
WHERE id=5;
So what I need is something like this: (this doesn't work)
SELECT z.rank FROM
(SELECT p.id, p.name,
(SELECT ban FROM u.users WHERE id=p.account_id) as banned, #rownum := #rownum + 1 AS rank FROM players p, (SELECT #rownum := 0) r
WHERE p.this != 'that' AND banned=0 ORDER BY p.cash + p.bank DESC) as z #
WHERE id=5;
Getting too complex for me!

Mysql query to get the row position in a table

I have table with id (store user id) and score in different match. I want what is the position of a user.
So for i try this sql fiddle;
in this I am getting all the row but I need only user having id 3 and it position in the table.
like this:
Score Postion
26 3
Even i try to do like this but no success
MySql: Find row number of specific record
With MySQL, how can I generate a column containing the record index in a table?
I got the answer: http://sqlfiddle.com/#!2/b787a/2
select * from (
select T.*,(#rownum := #rownum + 1) as rownum from (
select sum(score) as S,id from mytable group by id order by S desc ) as T
JOIN (SELECT #rownum := 0) r
) as w where id = 3
Updated sqlfiddle and above query. Now it is working perfectly.
I think this should do the trick:
SELECT totalScore, rownum FROM (
SELECT id,sum(score) AS totalScore,(#rownum := #rownum + 1) AS rownum
FROM mytable
JOIN (SELECT #rownum := 0) r
group by id) result
WHERE result.ID = 3;
just add a where clause
select x.id,x.sum,x.rownum
from(
select id,sum(score) as sum,(#rownum := #rownum + 1) as rownum
from mytable
JOIN (SELECT #rownum := 0) r
group by id
) x
where id =3

MySQL Ranking ID with Ties Based on Column Returns Error

I have a 1 table database with (in a simplified form) the following fields:
user_id(INT), ref_id(INT), points(INT), pointsgiven(BOOL/TINY_INT)
I want a query that returns the RANK of the user_id I specify based on points, given that pointsgiven is true. The kicker is, I need ties included. I can get a result set for ALL ranks if I want with the following query
SELECT
user_id, ref_id, points, pointsgiven,
CASE
WHEN #points = COALESCE(points, 0) THEN #rownum
ELSE #rownum := #rownum + 1
END AS rank,
#points := COALESCE(points, 0)
FROM users CT
JOIN
(
SELECT #rownum := 0, #points := NULL
) r
WHERE pointsgiven=TRUE ORDER BY points DESC
So, based on that, I thought I could just use that as a subquery to get a certain user_id as follows:
select * from
(
SELECT
user_id, ref_id, points, pointsgiven,
CASE
WHEN #points = COALESCE(points, 0) THEN #rownum
ELSE #rownum := #rownum + 1
END AS rank,
#points := COALESCE(points, 0)
FROM users CT
JOIN
(
SELECT #rownum := 0, #points := NULL
) r
WHERE pointsgiven=TRUE ORDER BY points DESC
) as derived WHERE user_id = 15
But this returns [BLOB - 1 B] as the rank on the correct user_id. What am I doing wrong here?
I have no idea why your query isn't working. For a single user id, though, you can use a correlated subquery:
select user_id, ref_id, points, pointsgiven,
coalesce((select count(distinct user_id)
from users u2
where u2.pointsgiven=TRUE and
u2.points > u.points
) + 1, 1) as rank
from users u
where user_id = 15;
An index on users(pointsgiven, points, user_id) should be used by the query.
To look at just one ranking, this might even be faster than your method.

COUNT() with nulls, inside subquery

I have a bit of a problem with an advanced query that I am struggling to get my head around.
Essentally there are votes in a votes table that correspond to a given soundtrack. My query needs to get a rank for a soundtrack based on the votes that it has been awarded.
My approach below works just fine when there are votes in the table but the rank is given a NULL value when there are none in there.
Here's the query:
SELECT soundtrack.*,
(SELECT WrappedQuery.rank
FROM (SELECT #rownum := #rownum + 1 AS rank,
prequery.soundtrack_id
FROM (SELECT #rownum := 0) sqlvars,
(SELECT Count(*),
soundtrack_id
FROM vote
GROUP BY vote.soundtrack_id
ORDER BY Count(*) DESC) prequery) WrappedQuery
WHERE WrappedQuery.soundtrack_id = soundtrack.id) AS rank
FROM soundtrack
WHERE soundtrack.id = 33
AND live = 1
ORDER BY rank ASC
I have a feeling the problem is to do with the (SELECT COUNT(*)) part, but everything I have tried so far isn't working out.
Hoping someone could shed some light on my issue.
EDIT
Here's the SQLFiddle
http://www.sqlfiddle.com/#!2/c8db2/2/0
THAT ONE IS GOOD:
SELECT soundtrack.*,
(SELECT WrappedQuery.rank
FROM (SELECT #rownum := #rownum + 1 AS rank,
prequery.soundtrack_id
FROM (SELECT #rownum := 0) sqlvars,
(
SELECT COALESCE(COUNT(vote.soundtrack_id),0) AS no_rows,
soundtrack.id AS soundtrack_id
FROM soundtrack
LEFT JOIN vote ON soundtrack.id=vote.soundtrack_id
GROUP BY soundtrack.id
ORDER BY 1 DESC
) prequery) WrappedQuery
WHERE WrappedQuery.soundtrack_id = soundtrack.id) AS rank
FROM soundtrack
ORDER BY rank ASC;
SEE: http://www.sqlfiddle.com/#!2/74698/2/0
I've had some luck ranking in my own work using the row_number function. But otherwise, the coalesce function might help you out.
SELECT soundtrack.*, rankquery.rank
FROM (
SELECT row_number() over(partition by prequery.soundtrack_id order by prequery.num_votes) as rank,
prequery.soundtrack_id
FROM (
SELECT COALESCE(COUNT(*),0) as num_votes, soundtrack_id
FROM vote
GROUP BY soundtrack_id
ORDER BY num_votes DESC
) prequery
) rankquery
INNER JOIN soundtrack
rankquery.soundtrack_id = soundtrack.id
WHERE soundtrack.id = 33
AND live = 1
ORDER BY rank
SELECT soundtrack.*, rankquery.rank
FROM(
SELECT prequery.*, #rownum := #rownum + 1 AS rank
(
SELECT COALESCE(Count(*),0) as num_votes,
soundtrack_id
FROM vote
GROUP BY soundtrack_id
ORDER BY num_votes DESC
) as prequery,
(SELECT #rownum := 0) as sqlvars
) rankquery
INNER JOIN soundtrack
rankquery.soundtrack_id = soundtrack.id
WHERE soundtrack.id = 33
AND soundtrack.live = 1
ORDER BY rankquery.rank ASC