SQL - Get next set of xx items - sql

I have a web API that returns the next "set" of x number of items based on the ID of the last item that was recieved. So, if my last item ID was 30, and I want 50 more, then I should get IDs 31 - 81.
If I implement an SQL query that says SELECT * FROM table WHERE ID > 30 LIMIT 50, am I guaranteed to get IDs 31 - 81? Or, is there a way to do that? The ID column is AUTOINCREMENT.
Also, this is SQLite, specifically. I am not sure if that matters.

You should also order them by id before limiting the number of results
SELECT * FROM table WHERE ID > 30
order by ID
LIMIT 50

Usually in SQLite you would do something like this:
SELECT * FROM table LIMIT 50 OFFSET 30;
See http://www.sqlite.org/lang_select.html for documentation.

Related

Retrieving "pages" with some number of rows using SQL

In PostgreSQL: To retrieve 100 rows using an SQL query we can use LIMIT 100.
Is there a way to retrieve first 100 rows and later the next 100 like doing some kind of pagination? i.e.
if I do something like:
SELECT ..... LIMIT 100;
and later execute a command like:
SELECT ... LIMIT 100
I could get the next 100 rows to the previous retrieval of 100 rows and so on?
Thanks in advance
Yes, you need to use limit combined with offset. You can find more details here
select * from table LIMIT 100 OFFSET 100*0 --first 100
select * from table LIMIT 100 OFFSET 100*1 --second 100

How to use seek pagination in SQL when going back a page? (Postgres)

I want to create a pagination with seek method (by using an index).
On the first page I want to have the newest records (with the highest ids) so when I go to next pages the ids should be lower and lower.
Lets say I have 100 users in database. So my first query to get the first page would be this:
SELECT * FROM users ORDER BY id DESC LIMIT 10
To fetch another page I need to use index:
SELECT * FROM users WHERE id < 90 ORDER BY id DESC LIMIT 10
And if I want to fetch next pages I just do id < 80, id < 70 etc. and it works fine.
But what if I want to go page back?
Right now I do this: (change < to > and DESC to ASC)
SELECT * FROM users WHERE id > 89 ORDER BY id ASC LIMIT 10
This fetches desired records, but the problem is they are sorted vice versa.
What I get:
90 | tom#gmail.com
91 | patrick#gmail.com
92 | jimmy#gmail.com
...
What I want to get:
100 | hannah#gmail.com
99 | dog#gmail.com
98 | hello#gmail.com
...
My questions:
Is my implementation of this pagination method correct? Maybe i'm doing something completly wrong?
If my approach is correct, how should I get the records in correct order? Is it possible to do it in SQL or the only way is to sort the results afterwards on the server?
Get your rows with the current order is a sub query then resort on the outer:
select *
from (select *
from users
where id > 89
order by id asc
limit 10
)
order by id desc;

In Sql Server 2014 ORDER BY clause with OFFSET FETCH NEXT returns weird results

I am currently using Sql Server 2014 Professional and the current version is (12.0.4100). I have a View and I am trying to SELECT 10 rows with specific offset.My View is like below:
BeginTime | EndTime | Duration | Name
09:00:00.0000000|16:00:00.0000000| 1 | some_name1
09:00:00.0000000|16:00:00.0000000| 2 | some_name2
09:00:00.0000000|16:00:00.0000000| 3 | some_name3
09:00:00.0000000|16:00:00.0000000| 4 | some_name4
09:00:00.0000000|16:00:00.0000000| 5 | some_name5
09:00:00.0000000|16:00:00.0000000| 6 | some_name6
09:00:00.0000000|16:00:00.0000000| 7 | some_name7
there are 100 rows like these and all have the exact same value in BeginTime and EndTime. Duration is incremented from 1 to 100 in related table. If query is only:
SELECT * FROM View_Name
ResultSet is correct. I can understand it by checking the duration column.
If I want to fetch only 10 rows starting from 0, ResultSet is correct and it is correct for starting from up to 18. When I want to fetch 10 rows starting from 19 or more than 19, Duration in ResultSet returns irrelevant results like Duration reversed. But it never returns the rows which has duration more than 11.
The query that I used to fetch specific rows is as follows:
SELECT * FROM View_Name ORDER BY BeginTime ASC OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
There is also something strange in this situation; if I specify USE master, this problem disappears, but, if I specify USE [mydb_name], the problem appears again. By the way, I am using SQL SERVER 2014 Professional v(12.0.2269) in my local pc, this problem disappears for the above situation.
PS: I can not use USE master because, I am creating and listing the view dynamically, in Stored Procedures. Any help, answer or comment will be accepted. Thank You!
The documentation explains:
To achieve stable results between query requests using OFFSET and
FETCH, the following conditions must be met:
. . .
The ORDER BY clause contains a column or combination of columns that are guaranteed to be unique.
What happens in your case is that BeginTime is not unique. Databases in general -- and SQL Server in particular -- do not implement stable sorts. A stable sort is one where the rows are in the same order when the keys are the same. This is rather obvious, because tables and result sets represent unordered sets. They have no inherent ordering.
So, you need a unique key to make the sort stable. Given your data, this would seem to be either duration, name, or both:
SELECT *
ROM View_Name
ORDER BY BeginTime ASC, Duration, Name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
your order by should be unique,otherwise you will get indeterministic results(in your case ,begin time is not unique and your are not guarnteed to get same results every time).try changing your query to below to make it unique..
SELECT * FROM View_Name ORDER BY duration OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
Further to add ,your first query (select * from view) result set is not guaranteed to be accurate every time unless you have an outer order by .

PostgreSQL:How get last rows from a select query

See the below example,
create table data(name varchar, value int);
insert into data values('joe',1);
insert into data values('bob',2);
insert into data values('jane',3);
insert into data values('anne',4);
insert into data values('kate',5);
And if I Execute
select * from data limit 2;
Will Get
name | value
------+-------
joe | 1
bob | 2
(2 rows)
So,How Can I Get the Last 2 Rows in select * from data?
What I'm expecting is....
name | value
------+-------
anne | 4
kate | 5
(2 rows)
You have two options according to your need i.e,
select * from data order by value desc limit 2
Or
LIMIT and OFFSET
if you want the 4th and 5th row just offset the first 3 so that the 4th row becomes the start of our set and you can specify a limit to say that you only want 2 rows from that.
select * from data offset 3 limit 2;
/* The order of LIMIT and OFFSET does not matter. This gives the same result */
select * from data limit 2 offset 3;
I know I'm answering a six year old question and I know the accepted answer says to use an offset, however that's only going to be useful if you know the length of the table. Looking at the wording of the question and the example given, I assumed that like myself, the author wanted the last entries in a table based on an id or other value in the order that they were entered.
The best solution I've found so far that orders the values as expected is using a subquery as follows:
SELECT * FROM ( SELECT * FROM data ORDER BY VALUE DESC LIMIT 2) AS _ ORDER BY VALUE ASC;
You'd substitute VALUE for whichever column you'd want to sort by to get the "last" entries. In my experience, this method is an order of magnitude quicker than using a count to find an offset.
To get the x last rows, example with x=10,
use offset alone, with count:
SELECT *
FROM data
ORDER BY value ASC
OFFSET (SELECT count(*) FROM DATA)-10
I let you check if the offset is not negative...
Make use of Order by Clause
select * from data order by value desc limit 2;
OR
select top 2 * from data order by value desc ;
You can achieve it using Order by clause desc
SELECT *
FROM data
ORDER BY value DESC limit 2;
like does Krishraj Rana you can try this function for get the last row with "limit 1" and order by "x col" desc, complete it "by x_col desc limit 1".

In SQL, how do you get the top N rows ordered by a certain column?

I want to select the top N rows of a table, ranked by how high the number in one of their columns is.
I already have:
SELECT * FROM movie ORDER BY worldwide_gross DESC;
How can I get the first twenty?
If it makes any difference I'm using MySQL.
Cheers!
Definition: Limit is used to limit your MySQL query results to those that fall within a specified range. You can use it to show the first X number of results, or to show a range from X - Y results. It is phrased as Limit X, Y and included at the end of your query. X is the starting point (remember the first record is 0) and Y is the duration (how many records to display).
Also Known As: Range Results
Examples:
SELECT * FROM `your_table` LIMIT 0, 10
This will display the first 10 results from the database.
SELECT * FROM `your_table` LIMIT 5, 5
This will show records 6, 7, 8, 9, and 10
More from About.com
I believe:
SELECT *
FROM movie
ORDER BY worldwide_gross DESC
LIMIT 20
should do the trick. See also this link.