In the MS SQL Management studio you can select
top n row as an action in the table menu.
I know how configuring the number of returned rows.
I want to now if there is a way to configure to return rows in desc ordering ?
If it were possible to determine if there was an identity primary key you could default to using that as the descending order, this would be usefull for showing the most recent items first? But there doesn't seem to be a way to get at the template used to generate the SQL so I think the answer is NO.
You have to modify the generated query and add an ORDER BY clause to it. Management Studio can't know by which column you want to sort.
SELECT *
FROM
(
SELECT t.*, ROW_NUMBER() OVER(order by ... desc) rn
FROM table t
)
WHERE rn < requiredQuantity
Related
I have few questions in context of the older row_number (SQL Server 2008) and the newer OFFSET + FETCH (SQL Server 2012) paging mechanism provided by SQL Server 2012.
What are the limitations with row_number()?
Is OFFSET + FETCH an improved replacement for row_number()?
Are there any use-cases which could only be sufficed using one and not the other?
Are there any performance differences between the two? If yes, which one is recommended?
Thanks.
Using ROW_NUMBER() works fine - it's just more work than necessary; you need to write a "skeleton" CTE around your actual query, add the ROW_NUMBER() column to your output set, and then filter on that.
Using the new OFFSET / FETCH is simpler - and yes, it's also better for performance, as these two links can show you:
New T-SQL features in SQL Server 2012
Comparing performance for different SQL Server paging
So overall: if you're using SQL Server 2012 - then you should definitely use OFFSET/FETCH rather than ROW_NUMBER() for paging
By definition ROW_NUMBER is a temporary value calculated when the query is run. OFFSET / FETCH is an option that you can specify for the ORDER BY clause.
In terms of speed, they both achieve great performance and the difference between each method depends on the columns that you specify in the SELECT clause and the Indexes that you have on your tables.
In the following 2 examples, you can see a difference between the two methods:
1. Case when OFFSET / FETCH is faster:
SELECT
Id
FROM Orders
ORDER BY
Id
OFFSET 50000 ROWS FETCH NEXT 5000 ROWS ONLY
SELECT
A.Id
FROM
(
SELECT
Id,
ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber FROM Orders
) AS A
WHERE
A.RowNumber BETWEEN 50001 AND 55000
2. Case when ROW_NUMBER() is faster:
SELECT
*
FROM Orders
ORDER BY
Id
OFFSET 50000 ROWS FETCH NEXT 5000 ROWS ONLY
SELECT
A.*
FROM
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber FROM Orders
) AS A
WHERE
A.RowNumber BETWEEN 50001 AND 55000
I found this article which presents 3 techniques of paging compares their results in a chart. Might be helpful in deciding which approach you want to follow.
Paging Function Performance in SQL Server 2012
All of the paging methods discussed work fine for smaller amounts of records, but not so much for larger quantities of data.
I have searched for paging in SQL Server. I found most of the solution look like that
What is the best way to paginate results in SQL Server
But it don't meet my expectation.
Here is my situation:
I work on JasperReport, for that: to export the report I just need pass the any Select query into the template, it will auto generated out the report
EX : I have a select query like this:
Select * from table A
I don't know any column names in table A. So I can't use
Select ROW_NUMBER() Over (Order By columsName)
And I also don't want it order by any columns.
Anyone can help me do it?
PS: In Oracle , it have rownum very helpful in this case.
Select * from tableA where rownum > 100 and rownum <200
Paging with Oracle
You should use ROW_NUMBER with an ORDER BY - because without an ORDER BY there is no determinism in how rows are returned. You can run the same query three times and get the results back in three different orders. Especially if merry-go-round scans come into play.
So unless you want your report to have the possibility of showing the same rows to users on multiple pages, or some rows never on any page, you need to find a way to order the result set to make it deterministic.
From my opinion, you can use sql query to find out how many columns in a table, and then find out a proper one for ' order by ' to depend on.
The script of how to get out columns of an table refer to : How can I get column names from a table in SQL Server?
Check out this link
http://msdn.microsoft.com/en-us/library/ms186734.aspx
SQL Server has similar function ROW_NUMBER. Though it behaves a bit differently.
SQL Server provides no guarantee of row order unless you have have specified a column in order by clause. I would recommend that you give an order by clause that has unique values.
Thank for all your help. Because of order by are required when paging in MS SQL Server, so I used ResultSetMetaData to get the Columns name and do paging as well.
You can use the below query aswell.
declare #test table(
id int,
value1 varchar(100),
value2 int)
insert into #test values(1,'10/50',50)
insert into #test values(2,'10/60',60)
insert into #test values(3,'10/60',61)
insert into #test values(4,'10/60',10)
insert into #test values(5,'10/60',11)
insert into #test values(6,'10/60',09)
select *
from ( select row_number() over (order by (select 0)) as rownumber,* from #test )test
where test.rownumber<=5
I have a view in my sql server 2005 db.
I'm using Pythons PyMsSQL to select rows form the view. I'm not necessarily selecting all the rows in the view with this select. For example, I might select based on name or date etc.
How can I page this view? That is, how can I select row 0 to 9, or rows 10 to 19 etc.
Thanks for your help,
Barry
One option is to use the ROW_NUMBER window function to
add a number you can select on
using an ORDER BY date, name or any other column that guarantees the order between subsequent runs.
SQL Statement
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY Date ) AS RowNum, *
FROM AView
) AS AView
WHERE RowNum BETWEEN 1 AND 9
I have been fighting with this all weekend and am out of ideas. In order to have pages in my search results on my website, I need to return a subset of rows from a SQL Server 2005 Express database (i.e. start at row 20 and give me the next 20 records). In MySQL you would use the "LIMIT" keyword to choose which row to start at and how many rows to return.
In SQL Server I found ROW_NUMBER()/OVER, but when I try to use it it says "Over not supported". I am thinking this is because I am using SQL Server 2005 Express (free version). Can anyone verify if this is true or if there is some other reason an OVER clause would not be supported?
Then I found the old school version similar to:
SELECT TOP X * FROM TABLE WHERE ID NOT IN (SELECT TOP Y ID FROM TABLE ORDER BY ID) ORDER BY ID where X=number per page and Y=which record to start on.
However, my queries are a lot more complex with many outer joins and sometimes ordering by something other than what is in the main table. For example, if someone chooses to order by how many videos a user has posted, the query might need to look like this:
SELECT TOP 50 iUserID, iVideoCount FROM MyTable LEFT OUTER JOIN (SELECT count(iVideoID) AS iVideoCount, iUserID FROM VideoTable GROUP BY iUserID) as TempVidTable ON MyTable.iUserID = TempVidTable.iUserID WHERE iUserID NOT IN (SELECT TOP 100 iUserID, iVideoCount FROM MyTable LEFT OUTER JOIN (SELECT count(iVideoID) AS iVideoCount, iUserID FROM VideoTable GROUP BY iUserID) as TempVidTable ON MyTable.iUserID = TempVidTable.iUserID ORDER BY iVideoCount) ORDER BY iVideoCount
The issue is in the subquery SELECT line: TOP 100 iUserID, iVideoCount
To use the "NOT IN" clause it seems I can only have 1 column in the subquery ("SELECT TOP 100 iUserID FROM ..."). But when I don't include iVideoCount in that subquery SELECT statement then the ORDER BY iVideoCount in the subquery doesn't order correctly so my subquery is ordered differently than my parent query, making this whole thing useless. There are about 5 more tables linked in with outer joins that can play a part in the ordering.
I am at a loss! The two above methods are the only two ways I can find to get SQL Server to return a subset of rows. I am about ready to return the whole result and loop through each record in PHP but only display the ones I want. That is such an inefficient way to things it is really my last resort.
Any ideas on how I can make SQL Server mimic MySQL's LIMIT clause in the above scenario?
Unfortunately, although SQL Server 2005 Row_Number() can be used for paging and with SQL Server 2012 data paging support is enhanced with Order By Offset and Fetch Next, in case you can not use any of these solutions you require to first
create a temp table with identity column.
then insert data into temp table with ORDER BY clause
Use the temp table Identity column value just like the ROW_NUMBER() value
I hope it helps,
What's the best method to do paging in my ASP page when displaying a list of items?
I knew that there is no equivalent to MySQL's LIMIT clause present in SQL Server, either 2000 or 2005.
How can I retrieve some particular records (Records 20 to 30) from the DB?
Do i need to fetch all the records from the database and do something in my ASP page to display the required records?
Whats the best method to do paging in my ASP page when displaying a list of items ?
I just want to add one more feature to Mr. Wheat's answer. Why not u are trying to use the Take () and Skip() feature of linq(obviously if u are using dotnet framework 3.5+)
It is indeed helpful while working with large datasets.
Have a look
Using Take and Skip method in LINQ queries
I knew that there is no MySQL LIMIT clause present in SQL server(both 2000 and 2005 should support).how can i retrieve some particular records (Record 20 -30) from DB ?
You can do this in SQLSERVER 2005+ by using ranking function Row_Number() among other alternatives. A sample example is included herewith
First I am creating a dummy table and inserting some 50 records
declare #tbl table(name varchar(50),age int)
;with num_cte as
( select 1 as rn
union all
select rn+1 from num_cte where rn<50
)
insert #tbl
select names ,rn + 20 ageval
from num_cte
cross apply( select 'name' + CAST(rn as varchar(2)) AS names) names
select * from #tbl
Now by using the Row_Number() function I am picking up records between 20 & 30
select name,age from(
select ROW_NUMBER()over (order by age) as rownum,name,age from #tbl) X
where X.rownum between 20 and 30
However, for achieving the same in SQL SERVER 2000 the below query will help
select name,age from(
select t1.name,t1.age,
(select count(*)+1 from #tbl where name<>t1.name and age<=t1.age) rownum
from #tbl t1
)X(name,age,rownum)
where rownum between 20 and 30
Please see:
Paging In ASP.NET
Data Access Tutorials
GridView Examples for ASP.NET 2.0: Paging and Sorting the GridView's Data
SQL Server 2005 Paging – The Holy Grail
Youd need to use ROW_NUMBER (SQL Server 2005+)
SELECT * FROM
(SELECT a.*, ROW_NUMBER() OVER (ORDER BY hire_date) rn
FROM hr.employees AS OF TIMESTAMP (TIMESTAMP '2009-01-29 10:30:00') a)
WHERE rn BETWEEN 10 AND 19
Related answer
Using ROW_NUMBER, you are numering and sorting the inherently unsorted group (the table). Once you have an ordered set instead of just a set, you can now the sentence "I want all the rows from 10 to 19" makes sense.
You will have to use ASP code to keep both the upper and lower elements, so you can ask for the next or previous subset of rows to show.