I am looking for help converting my MySQL query to work in PostgreSQL. This is a query on the model of RoR application.
Any help is appreciated.
SELECT * FROM(
SELECT #row := #row + 1 AS rownum, id, device_id, name, quarterly
FROM (SELECT #row :=0) r, recurrent_tests
WHERE device_id = "+self.id.to_s+" AND quarterly = 1
ORDER BY name ASC
) ranked
WHERE (rownum-1) % 4 = "+(i-1).to_s)
select *
from (
select row_number() over (order by name asc) as rownum,
id,
device_id,
name,
quarterly
from recurrent_tests
) t
where rownum - 1 % 4 = ...
For more details on window functions (the over (...) clause) please see the manual:
http://www.postgresql.org/docs/current/static/tutorial-window.html
Related
I am trying to get 2% of the random sample record.
SELECT * FROM Orders
ORDER BY RAND()
LIMIT (SELECT CEIL(0.02 * (SELECT COUNT(*) FROM Orders)));
This one gives a syntax error due to line 3. Is there anything I am doing wrong?
Or is there a better way to get n % of records?
If you are using MySQL 8+, then ROW_NUMBER() provides one option:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY RAND()) rn,
COUNT(*) OVER () cnt
FROM Orders
)
SELECT *
FROM cte
WHERE 1.0*rn / cnt <= 0.02;
On MySQL 5.7 and earlier, we can simulate row number:
SELECT *
FROM
(
SELECT *, (#rn := #rn + 1) AS rn
FROM Orders, (SELECT #rn := 0) AS x
ORDER BY RAND()
) t
CROSS JOIN (SELECT COUNT(*) AS cnt FROM Orders) o
WHERE 1.0*rn / cnt <= 0.02;
Query stopped working (getting the user's position in the leaderboard):
SELECT
`rank`, `uid`, `battleWinScore`
FROM
(SELECT
#rank:=#rank+1 AS `rank`, `uid`, `battleWinScore`
FROM
`rating`, (SELECT #rank := 0) r
ORDER BY `battleWinScore` DESC
) t
WHERE uid = 572;
In the rating table, we need to get the user's position by field battleWinScore.
I am absolutely not good at mysql. Help =)
If you are running MySQL 8.0, just use row_number() (or rank(), if you want to consistently allow ties).
select *
from (
select uid, battleWinScore, rank() over(order by battleWinScore desc) rn
from rating
) r
where uid = 572
In earlier versions, I would recommend a correlated subquery rather than user variables:
select uid, battleWinScore
(select count(*) + 1 from rating r1 where r1.battleWinScore > r.battleWinScore) as rn
from rating r
where uid = 572
I trying to use mysql to solve the following solutions:
https://www.hackerrank.com/challenges/weather-observation-station-20/problem
Understanding that a variable cannot be put into LIMIT statement (from this )
My approach>
to declare a new variable to record rowIDs, and use rowID to retrieve the record in the middle.
However, it seems that rowID is not working well.
Could anyone give me some advises?
SELECT ROUND(COUNT(LAT_N)/2,0) FROM STATION into #count;
SELECT ROUND(a.LAT_N,4) FROM (
SELECT *,#row := #row + 1 FROM STATION s, (SELECT #row := 0) r
WHERE #row <=#count
ORDER BY s.LAT_N ASC) a
ORDER BY a.LAT_N DESC LIMIT 1;`
If you are running MySQL 8.0, this is simpler done with window functions:
select round(avg(lat_n), 4) median_lat_n
from (
select s.*, row_number() over(orer by lat_n) rn
from station s
where lat_n is not null
) s
where rn * 2 in (rn - 1, rn, rn + 1)
In earlier versions, variables make it bit tricky; we need one more level of nesting to make it safe:
select round(avg(lat_n), 2) median_lat_n
from (
select s.*, #rn := #rn + 1 rn
from (select * from station order by lat_n) s
cross join (select #rn := 0) p
) s
where rn * 2 in (rn - 1, rn, rn + 1)
The logic is as follows: first enumerate the rows, ordered by lat_n. If the row count is uneven, we pick the middle row; if it is even, we take the average of the two middle values.
SELECT * FROM ( SELECT #row := #row +1 AS rownum, [column name] FROM ( SELECT * FROM [table name] ) WHERE rownum % 5 = 1
This does indeed return every 5th row, but in ascending order. What I want is that it first gets all the data, put them in descending order and THEN apply the filter.
If you filter it first and then put it in descending order, it will not start with the latest data added (4/5th of the time).
I would like to know how one should do this.
Thanks in advance
Edit: For people with the same problem, this is what I used:
SELECT * FROM
(SELECT rank, id, Temperature FROM
(SELECT *, #rownum := #rownum + 1 AS rank FROM temperature_room1,
(SELECT #rownum := 0) r) AS T ORDER BY id DESC) AS J WHERE rank % 5 = 1
Select everything from:
Select rank, id and Temperature from:
Select everything and rownumber as rank from the table as t ordered by ID in descending order
Finally, only output the row numbers which can be divided by 5 and the remainder is 1
Don't quote me on this, I'm a big noob regarding SQL stuff. It works for me, so I'm happy.
seems like you just need an order by dec on the desired column in one of the three queries. I think the second one as order by applies to the select at the same level. ans since you want your rownum ordered desc... seems like that's the place...
SELECT *
FROM ( SELECT #row := #row +1 AS rownum, [column name]
FROM ( SELECT * FROM [table name] )
ORDER BY [column name] desc
)
WHERE rownum % 5 = 1
I am using the following code in MySQL server to get entries between 2 to 5 from table 'new_table' but I am receiving 'missing parenthesis' error, I have checked every aspect.
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY salary ASC) AS row number
FROM pact
) as temp table name
WHERE rownumber IN (2,5)
if your using a MySql-Server there is nothing like ROW_NUMBER()
but you could try something like this (UNTESTET):
SELECT * FROM (
SELECT
#num := if(#type = type, #num + 1, 1) as rownumber
FROM pact
ORDER BY salary ASC
) as temp_table_name
WHERE rownumber IN (2,5)
You can't use space in alias
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY salary ASC) AS rownumber
FROM pact
) as temp_table_name
WHERE rownumber IN (2,5)