How to skip the first n rows in sql query - sql

I want to fire a Query "SELECT * FROM TABLE" but select only from row N+1. Any idea on how to do this?

For SQL Server 2012 and above, use this:
SELECT *
FROM Sales.SalesOrderHeader
ORDER BY OrderDate
OFFSET (#Skip) ROWS FETCH NEXT (#Take) ROWS ONLY
https://stackoverflow.com/a/19669165/1883345

SQL Server:
select * from table
except
select top N * from table
Oracle up to 11.2:
select * from table
minus
select * from table where rownum <= N
with TableWithNum as (
select t.*, rownum as Num
from Table t
)
select * from TableWithNum where Num > N
Oracle 12.1 and later (following standard ANSI SQL)
select *
from table
order by some_column
offset x rows
fetch first y rows only
They may meet your needs more or less.
There is no direct way to do what you want by SQL.
However, it is not a design flaw, in my opinion.
SQL is not supposed to be used like this.
In relational databases, a table represents a relation, which is a set by definition. A set contains unordered elements.
Also, don't rely on the physical order of the records. The row order is not guaranteed by the RDBMS.
If the ordering of the records is important, you'd better add a column such as `Num' to the table, and use the following query. This is more natural.
select *
from Table
where Num > N
order by Num

Query: in sql-server
DECLARE #N INT = 5 --Any random number
SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RoNum
, ID --Add any fields needed here (or replace ID by *)
FROM TABLE_NAME
) AS tbl
WHERE #N < RoNum
ORDER BY tbl.ID
This will give rows of Table, where rownumber is starting from #N + 1.

In order to do this in SQL Server, you must order the query by a column, so you can specify the rows you want.
Example:
select * from table order by [some_column]
offset 10 rows
FETCH NEXT 10 rows only

Do you want something like in LINQ skip 5 and take 10?
SELECT TOP(10) * FROM MY_TABLE
WHERE ID not in (SELECT TOP(5) ID From My_TABLE ORDER BY ID)
ORDER BY ID;
This approach will work in any SQL version. You need to stablish some order (by Id for example) so all rows are provided in a predictable manner.

I know it's quite late now to answer the query. But I have a little different solution than the others which I believe has better performance because no comparisons are performed in the SQL query only sorting is done. You can see its considerable performance improvement basically when value of SKIP is LARGE enough.
Best performance but only for SQL Server 2012 and above. Originally from #Majid Basirati's answer which is worth mentioning again.
DECLARE #Skip INT = 2, #Take INT = 2
SELECT * FROM TABLE_NAME
ORDER BY ID ASC
OFFSET (#Skip) ROWS FETCH NEXT (#Take) ROWS ONLY
Not as Good as the first one but compatible with SQL Server 2005 and above.
DECLARE #Skip INT = 2, #Take INT = 2
SELECT * FROM
(
SELECT TOP (#Take) * FROM
(
SELECT TOP (#Take + #Skip) * FROM TABLE_NAME
ORDER BY ID ASC
) T1
ORDER BY ID DESC
) T2
ORDER BY ID ASC

What about this:
SELECT * FROM table LIMIT 50 OFFSET 1

This works with all DBRM/SQL, it is standard ANSI:
SELECT *
FROM owner.tablename A
WHERE condition
AND n+1 <= (
SELECT COUNT(DISTINCT b.column_order)
FROM owner.tablename B
WHERE condition
AND b.column_order>a.column_order
)
ORDER BY a.column_order DESC

PostgreSQL: OFFSET without LIMIT
This syntax is supported, and it is in my opinion the cleanest API compared to other SQL implementations as it does not introduce any new keywords:
SELECT * FROM mytable ORDER BY mycol ASC OFFSET 1
that should definitely be standardized.
The fact that this is allowed can be seen from: https://www.postgresql.org/docs/13/sql-select.html since LIMIT and OFFSET can be given independently, since OFFSET is not a sub-clause of LIMIT in the syntax specification:
[ LIMIT { count | ALL } ]
[ OFFSET start [ ROW | ROWS ] ]
SQLite: negative limit
OFFSET requires LIMIT in that DBMS, but dummy negative values mean no limit. Not as nice as PostgreSQL, but it works:
SELECT * FROM mytable ORDER BY mycol ASC LIMIT -1 OFFSET 1
Asked at: SQLite with skip (offset) only (not limit)
Documented at: https://sqlite.org/lang_select.html
If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned.
MySQL: use a huge limit number
Terrible API design, the documentation actually recommends it:
SELECT * FROM tbl LIMIT 1,18446744073709551615;
Asked at: MySQL skip first 10 results
Node.js Sequelize ORM implements it
That ORM allows e.g. findAll({offset: without limit:, and implements workarounds such as the ones mentioned above for each different DBMS.

In Faircom SQL (which is a pseudo MySQL), i can do this in a super simple SQL Statement, just as follows:
SELECT SKIP 10 * FROM TABLE ORDER BY Id
Obviously you can just replace 10 with any declared variable of your desire.
I don't have access to MS SQL or other platforms, but I'll be really surprised MS SQL doesn't support something like this.

DECLARE #Skip int= 2, #Take int= 2
SELECT * FROM TABLE_NAME
ORDER BY Column_Name
OFFSET (#Skip) ROWS FETCH NEXT (#Take) ROWS ONLY

try below query it's work
SELECT * FROM `my_table` WHERE id != (SELECT id From my_table LIMIT 1)
Hope this will help

You can also use OFFSET to remove the 1st record from your query result like this-
Example - find the second max salary from the employee table
select distinct salary from employee order by salary desc limit 1 OFFSET 1

For SQL Server 2012 and later versions, the best method is #MajidBasirati's answer.
I also loved #CarlosToledo's answer, it's not limited to any SQL Server version but it's missing Order By Clauses. Without them, it may return wrong results.
For SQL Server 2008 and later I would use Common Table Expressions for better performance.
-- This example omits first 10 records and select next 5 records
;WITH MyCTE(Id) as
(
SELECT TOP (10) Id
FROM MY_TABLE
ORDER BY Id
)
SELECT TOP (5) *
FROM MY_TABLE
INNER JOIN MyCTE ON (MyCTE.Id <> MY_TABLE.Id)
ORDER BY Id

Related

Last row of the table without using any function or where clause

In one of the technical interviews I was asked to find the last row of a Table without using where clause or any other defined sql functions. It was given that the table has integer ids as Primary key in the ascending order. I was only able to give an answer by order by desc of the table and later stuck on how to get the top row without where or any function. Can someone please help.
EDIT : There was no database constraint in the question. Assume any database which solves the query
In Oracle 11g and below, this is not possible as it does not support the TOP/LIMIT/FETCH syntax and you would normally do:
SELECT *
FROM (
SELECT *
FROM table_name
ORDER BY id DESC
)
WHERE ROWNUM = 1;
In PostgreSQL, Oracle 12 and SQL Server 2012 you can do:
SELECT *
FROM table_name
ORDER BY id DESC
OFFSET 0 ROWS -- This line is optional in Oracle 12, PostgreSQL
FETCH FIRST 1 ROW ONLY;
In SQL Server, you can use TOP:
SELECT TOP 1
*
FROM table_name
ORDER BY id DESC
In MySQL, you can use LIMIT:
SELECT *
FROM table_name
ORDER BY id DESC
LIMIT 1;
TRY ROWCOUNT for SQL-SERVER similarly you can use
ROWNUM or FETCH FIRST for ORACLE -- Do search for this, it quite easy to use
LIMIT for MYSQL -- Do search for this, it quite easy to use
SET ROWCOUNT 1
SELECT * FROM <table name> ORDER BY [id] DESC
Assuming tableID is the surrogate key implemented as an autonumber/autoincrement
SELECT TOP 1 FROM tTable Order by tableID DESC
There is no way to do this. Relational databases are not required to keep their rows in any particular order... So, there's no way of knowing which row is physically stored last. You'll need to use the ORDER BY.
You might be able to improve performance with some appropriate indexes. This sort of thing should be pretty fast with an index.

Oracle equivalent ROWNUM for SQL-Server 2005?

In Oracle PL/SQL I was used to write:
SELECT * FROM MY_TABLE WHERE ROWNUM <= 100;
in order to fetch only the first 100 records of the table named MY_TABLE.
What could be the equivalent SELECT statement in SQL SERVER?
In SQL-Server You can Use TOP to select the no. of rows.
SELECT TOP 100 * FROM MY_TABLE
select top 100 * from tbl
column name is required or use *
SELECT TOP 100 * FROM TABLE
You can also filter rows by using where class
SELECT TOP 100 * FROM YOURTABLE WHERE YOURCONDITION
In SQL Server 2012, you can use OFFSET and FETCH to determine which rows to return. They're documented under ORDER BY; This makes sense since asking for 100 rows, when tables are by definition unordered, gives unpredictable results.
Similarly, if you use other's answers, re: TOP, you should also have an ORDER BY clause, or else it's not defined which rows will be returned.
SELECT TOP 100 * FROM MY_TABLE
Sorry if I misunderstood.
Edit: Must be faster

SQL Server 2008 Paged Row Retrieval and Large Tables

I'm using SQL Server 2008 and the following query to implement paged data retrieval from our JSF application, in below code i am retrieving 25 rows at a time sorted by the default sort column in DESC order.
SELECT * FROM
(
SELECT TOP 25 * FROM
(
SELECT TOP 25 ...... WHERE CONDITIONS
--ORDER BY ... DESC
)AS INNERQUERY ORDER BY INNERQUERY.... ASC
)
AS OUTERQUERY
ORDER BY OUTERQUERY.... DESC
It works, but with one obvious flow. If the users request to see the last page and there are over 10 million records in table, then the second TOP Query will have to first retrieve the 10 million records and only then the first top Query will pick out the Top 25 which will look like:
SELECT * FROM
(
SELECT TOP 25 * FROM
(
SELECT TOP 10000000 ...... WHERE CONDITIONS
--ORDER BY ... DESC
)AS INNERQUERY ORDER BY INNERQUERY.... ASC
)
AS OUTERQUERY
ORDER BY OUTERQUERY.... DESC
I looked into replacing the above with ROW_NUMBER OVER(....) but seemingly i had the same issue where the second TOP statement will have to get the entire result and only then you can do a where ROW_NUMBER between x and y.
Can you please point out my mistakes in the above approach and hints on how it can be optimized?
I'm currently using the following to code to retrieve subset of rows:
WITH PAGED_QRY (
SELECT *, ROW_NUMVER() OVER(ORDER BY Y) AS ROW_NO
FROM TABLE WHERE ....
)
SELECT * FROM PAGED_QRY WHERE ROW_NO BETWEEN #CURRENT_INDEX and # ROWS_TO_RETRIEVE
ORDER BY ROW_NO
where #current_index and #rows_to_retrieve (ie. 1 and 50) are your paging variables. it's cleaner and easier to read.
I've also tried using SET ROW_COUNT #ROWS_TO_RETRIEVE but doesn't seem to make much difference.
Using above query and by carefully studying the execution path of the query and modifying/creating indexes and statistics I've reached results that are sufficiently satisfactory, hence why i'm making this as the answer. The original goal of retrieving only the required rows in the inner query seems to be not possible yet, if you do find the way please let me know.
we can improve above query a bit more.
If I assume that #current_index is the current page number then we can rewrite the above query as:
WITH PAGED_QRY (
SELECT top (#current_index * #rows_to_retrieve) *, ROW_NUMVER()
OVER(ORDER BY Y) AS ROW_NO
FROM TABLE WHERE ....
)
SELECT TOP #ROWS_TO_RETRIEVE FROM PAGED_QRY
ORDER BY ROW_NO DESC
In this case, our inner query will not return the whole record set. Suppose our page_index is 3 & page_size is 50, then it will select only 150 rows(even if our table contains hundreds/thousands/millions of rows) & we can skip the where clause also.

how to select first N rows from a table in T-SQL?

Is there any way to select, for example, first 10 rows of a table in T-SQL (working MSSQL)?
I think I saw something in Oracle defined as rownum meta variable, used in a following way
select * from Users where rownum<=10
But what about MSSQL?
select top(#count) * from users
If #count is a constant, you can drop the parentheses:
select top 42 * from users
(the latter works on SQL Server 2000 too, while the former requires at least 2005)
You can use Microsoft's row_number() function to decide which rows to return. That means that you aren't limited to just the top X results, you can take pages.
SELECT *
FROM (SELECT row_number() over (order by UserID) AS line_no, *
FROM dbo.User) as users
WHERE users.line_no < 10
OR users.line_no BETWEEN 34 and 67
You have to nest the original query though, because otherwise you'll get an error message telling you that you can't do what you want to in the way you probably should be able to in an ideal world.
Msg 4108, Level 15, State 1, Line 3
Windowed functions can only appear in the SELECT or ORDER BY clauses.
SELECT TOP 10 *
FROM Users
Note that if you don't specify an ORDER BY clause then any 10 rows could be returned, because "first 10 rows" doesn't really mean anything until you tell the database what ordering to use.
You can also use rowcount, but TOP is probably better and cleaner, hence the upvote for Mehrdad
SET ROWCOUNT 10
SELECT * FROM dbo.Orders
WHERE EmployeeID = 5
ORDER BY OrderDate
SET ROWCOUNT 0
Try this.
declare #topval int
set #topval = 5 (customized value)
SELECT TOP(#topval) * from your_database
SELECT TOP 10 * FROM TABLE_NAME ORDER BY ORDERED_UNIQUE_COLUMN
DESC
ORDERED_UNIQUE_COLUMN could be your incrementing primary key or a timestamp
Try this:
SELECT * FROM USERS LIMIT 10;

How to read the last row with SQL Server

What is the most efficient way to read the last row with SQL Server?
The table is indexed on a unique key -- the "bottom" key values represent the last row.
If you're using MS SQL, you can try:
SELECT TOP 1 * FROM table_Name ORDER BY unique_column DESC
select whatever,columns,you,want from mytable
where mykey=(select max(mykey) from mytable);
You'll need some sort of uniquely identifying column in your table, like an auto-filling primary key or a datetime column (preferably the primary key). Then you can do this:
SELECT * FROM table_name ORDER BY unique_column DESC LIMIT 1
The ORDER BY column tells it to rearange the results according to that column's data, and the DESC tells it to reverse the results (thus putting the last one first). After that, the LIMIT 1 tells it to only pass back one row.
If some of your id are in order, i am assuming there will be some order in your db
SELECT * FROM TABLE WHERE ID = (SELECT MAX(ID) FROM TABLE)
I think below query will work for SQL Server with maximum performance without any sortable column
SELECT * FROM table
WHERE ID not in (SELECT TOP (SELECT COUNT(1)-1
FROM table)
ID
FROM table)
Hope you have understood it... :)
I tried using last in sql query in SQl server 2008 but it gives this err:
" 'last' is not a recognized built-in function name."
So I ended up using :
select max(WorkflowStateStatusId) from WorkflowStateStatus
to get the Id of the last row.
One could also use
Declare #i int
set #i=1
select WorkflowStateStatusId from Workflow.WorkflowStateStatus
where WorkflowStateStatusId not in (select top (
(select count(*) from Workflow.WorkflowStateStatus) - #i ) WorkflowStateStatusId from .WorkflowStateStatus)
You can use last_value: SELECT LAST_VALUE(column) OVER (PARTITION BY column ORDER BY column)...
I test it at one of my databases and it worked as expected.
You can also check de documentation here: https://msdn.microsoft.com/en-us/library/hh231517.aspx
OFFSET and FETCH NEXT are a feature of SQL Server 2012 to achieve SQL paging while displaying results.
The OFFSET argument is used to decide the starting row to return rows from a result and FETCH argument is used to return a set of number of rows.
SELECT *
FROM table_name
ORDER BY unique_column desc
OFFSET 0 Row
FETCH NEXT 1 ROW ONLY
SELECT TOP 1 id from comission_fees ORDER BY id DESC
In order to retrieve the last row of a table for MS SQL database 2005, You can use the following query:
select top 1 column_name from table_name order by column_name desc;
Note: To get the first row of the table for MS SQL database 2005, You can use the following query:
select top 1 column_name from table_name;
If you don't have any ordered column, you can use the physical id of each lines:
SELECT top 1 sys.fn_PhysLocFormatter(%%physloc%%) AS [File:Page:Slot],
T.*
FROM MyTable As T
order by sys.fn_PhysLocFormatter(%%physloc%%) DESC
SELECT * from Employees where [Employee ID] = ALL (SELECT MAX([Employee ID]) from Employees)
This is how you get the last record and update a field in Access DB.
UPDATE compalints SET tkt = addzone &'-'& customer_code &'-'& sn where sn in (select max(sn) from compalints )
If you have a Replicated table, you can have an Identity=1000 in localDatabase and Identity=2000 in the clientDatabase, so if you catch the last ID you may find always the last from client, not the last from the current connected database.
So the best method which returns the last connected database is:
SELECT IDENT_CURRENT('tablename')
Well I'm not getting the "last value" in a table, I'm getting the Last value per financial instrument. It's not the same but I guess it is relevant for some that are looking to look up on "how it is done now". I also used RowNumber() and CTE's and before that to simply take 1 and order by [column] desc. however we nolonger need to...
I am using SQL server 2017, we are recording all ticks on all exchanges globally, we have ~12 billion ticks a day, we store each Bid, ask, and trade including the volumes and the attributes of a tick (bid, ask, trade) of any of the given exchanges.
We have 253 types of ticks data for any given contract (mostly statistics) in that table, the last traded price is tick type=4 so, when we need to get the "last" of Price we use :
select distinct T.contractId,
LAST_VALUE(t.Price)over(partition by t.ContractId order by created ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
from [dbo].[Tick] as T
where T.TickType=4
You can see the execution plan on my dev system it executes quite efficient, executes in 4 sec while the exchange import ETL is pumping data into the table, there will be some locking slowing me down... that's just how live systems work.
It is very simple
select top 10 * from TableName order by 1 desc
SELECT * FROM TABLE WHERE ID = (SELECT MAX(ID) FROM TABLE)
I am pretty sure that it is:
SELECT last(column_name) FROM table
Becaause I use something similar:
SELECT last(id) FROM Status