Why LIMIT и OFFSET (OFFSET ... ROWS FETCH FIRST ... ROW only) functions in PostgreSQL are not working? - sql

I am trying to use LIMIT and OFFSET functions or OFFSET ... ROWS
FETCH FIRST ... ROW only. PostgreSQL gives me the wrong number of rows in result.
select user_id, max(order_ts) as lastorder
from production.orders
group by user_id
order by lastorder desc, user_id desc
OFFSET 10 ROWS
FETCH FIRST 20 ROW only
or
select user_id, max(order_ts) as lastorder
from production.orders
group by user_id
order by lastorder desc, user_id desc
OFFSET 10
limit 20
Still gives me 20 rows (should be 10: from 10th row to 20th - is 10).
How is this? Any help, please?

LIMIT 20 tells server to return not more than 20 records. FETCH FIRST 20 ONLY is absolutely the same. The query might return 20 rows or less depending on the data and query conditions. If you are trying to get rows from 11th to 20th then you need to specify LIMIT 10 OFFSET 10.
See the paragraph LIMIT Clause in the documentation for details:
https://www.postgresql.org/docs/15/sql-select.html#SQL-LIMIT

Related

Rolling 31 day average including previous 31 days from BigQuery

I've created a query that returns a counts the number of rows (records) for the last 31 days (based on a timestamp field) and include the previous 31 days before that period as well, eg. produce a query that returns both. I now have the following query:
SELECT
COUNT(*) OVER(ORDER BY datetime DESC RANGE BETWEEN 2678400000 PRECEDING AND CURRENT ROW) AS rolling_avg_31_days,
COUNT(*) OVER(ORDER BY datetime DESC RANGE BETWEEN 5356800000 PRECEDING AND CURRENT ROW) AS rolling_avg_62_days
FROM `p`
ORDER BY rolling_avg_31_days DESC LIMIT 1
And it returns some data, but not really the data I was hoping for:
rolling_avg_31_days | rolling_avg_62_days
8,422,783 | 9,790,304
If I query the same table with (rolling 62 days):
SELECT COUNT(*) FROM `p`
WHERE datetime > UNIX_MILLIS(CURRENT_TIMESTAMP)-5356800000 AND datetime < UNIX_MILLIS(CURRENT_TIMESTAMP)-2678400000'
I get a value of 6,192,920
I'm not sure what I'm doing wrong. Any help is much appreciated!
So, the first query is correct and gives you rolling counts (31 and 62 days) based on the timestamp field - also, because of order by .. desc and limit 1 you are getting the most row that has biggest rolling_avg_31_days which is not necessarily row for the most recent () datetime
The second query just produces count of rows between 62 and 31 days based on the current timestamp - which is as explain above is not what first query produces - thus the discrepancy
To further troubleshoot or to try to understand difference - change ORDER BY rolling_avg_31_days DESC LIMIT 1 to ORDER BY datetime DESC LIMIT 1 and also add datetime to select statement so you can see if it belong to current date or close to current statement so results are comparable
Instead of going with the above, I've decided to change the query to be a bit simpler:
SELECT
(SELECT COUNT(DISTINCT(wasabi_user_id)) FROM `p` WHERE datetime > UNIX_MILLIS(CURRENT_TIMESTAMP)-5356800000 AND datetime < UNIX_MILLIS(CURRENT_TIMESTAMP)-2678400000) as _62days,
(SELECT COUNT(DISTINCT(wasabi_user_id)) FROM `p` WHERE datetime > UNIX_MILLIS(CURRENT_TIMESTAMP)-2678400000) AS _31days
FROM `mycujoo_kafka_public.v_web_event_pageviews` LIMIT 1
Thanks #Mikhail for the help though!

SQL - How to select a row having a column with max value without using sub query in Oracle

date value
18/5/2010 40
18/5/2010 20
20/5/2010 60
18/5/2010 30
17/5/2010 10
16/5/2010 40
18/5/2010 60
18/5/2010 25
Output
date value
18/5/2010 60
20/5/2010 60
I need to query for the row having max(value)(i.e. 60). So, here we get two rows.
the date can be in any order
Plz do not use SUBQUERY
I need a dynamic query without using sub query
NESTED QUERY will be fine ...
I have tried that using rownum ... Where rownum< some_value ...but it is not dynamic
In 12c the FETCH clause allows you to do this
select * from the_table
order by value desc
FETCH FIRST 1 ROWS WITH TIES;

Query rows 9,000,000 to 10,000,000

New to postgresql, I have a table with 10,000,000 rows, I've been querying data a million rows at a time
SELECT mmsi, report_timestamp, position_geom, ST_X(position_geom) AS Long,ST_Y(position_geom) AS Lat
FROM reports4
WHERE position_geom IS NOT NULL
ORDER by report_timestamp ASC
LIMIT 1000000
OFFSET 8000000
When I try and query the last million rows nothing shows up
SELECT mmsi, report_timestamp, position_geom, ST_X(position_geom) AS Long,ST_Y(position_geom) AS Lat
FROM reports4
WHERE position_geom IS NOT NULL
ORDER by report_timestamp ASC
LIMIT 1000000
OFFSET 9000000
Not sure If I'm doing the query right, or im overlooking something.
The table may have 10,000,000 rows, but how many of those rows have WHERE position_geom IS NOT NULL?
What do you get with:
SELECT count(*)
FROM reports4
WHERE position_geom IS NOT NULL;

Sql Statement that returns only the top 5 highest values in desc order, but the 5th en 6th value are the same?

Im struggling to retrieve only 5 values from my sql Statement. I want to retrieve the 5 highest numbers in a single column. The trouble is that some of the numbers repeat. When the 5th and the 6th highest numbers are the same my sql statement retrieves 6 values and not 5. If the 5th and the 6th number are the same i dont need the 6th number from the sql. Can anyone please help?
Here is the column:
Number
10
9
5
5
3
3
2
1
My results are:
Number
10
9
5
5
3
3
I would like to retrieve only first 5 numbers excluding the 6th number.
Here is my sql:
10
9
5
5
3
3
SELECT TOP 5 Number
FROM tbl
Order by Number Desc
You can group them and display like this:
SELECT TOP 5 Number
FROM tbl
GROUP BY Number
Order by Number Desc
or you can use DISTINCT:
SELECT DISTINCT TOP 5 Number
FROM tbl
Order by Number Desc
Just order by number desc, and limit it to 5
select Number from table
order by Number desc
limit 5;
Note, that is MySQL syntax, i have no idea if it is "standard" for other DBs. You don't specify what DB you are using.

Calculating running average with sqlite

I am using the following code to calculate a running average:
SELECT AVG(close) FROM daily
ORDER BY datum DESC
LIMIT 50
for a 50-day average. However, it doesn't seem to work. I can change LIMIT to 5, 10, 20. The result is always the same. Is the LIMIT just a visual limit maybe?
LIMIT restricts your result set, not the set you're averaging over. You'd want something like
SELECT AVG(close) FROM
(
SELECT close FROM daily ORDER BY datum DESC LIMIT 50
)