SQL query to update rows - sql

I have data in a table in following format
ID DocNumber RevOrder
1 DOC-001 NULL
2 DOC-001 NULL
3 DOC-001 NULL
4 DOC-002 NULL
5 D0C-002 NULL
6 D0C-003 NULL
I need to update the RevOrder column in to following format
ID DocNumber RevOrder
1 DOC-001 3
2 DOC-001 2
3 DOC-001 1
4 DOC-002 2
5 D0C-002 1
6 D0C-003 1
Logic is: DocNumber can be duplicated and the DocNumber with the max ID gets the RevOrder = 1, next get the RevOrder = 2 etc... how can I achieve the above scenario?

Use this UPDATE statement based on a ROW_NUMBER() over a partition:
;WITH UpdateData AS
(
SELECT
ID, DocNumber,
ROW_NUMBER() OVER(PARTITION BY DocNumber ORDER BY ID DESC) AS 'RowNum'
FROM dbo.YourTable
)
UPDATE dbo.YourTable
SET RevOrder = RowNum
FROM dbo.YourTable t
INNER JOIN UpdateData ud ON t.ID = ud.ID

from SQL Server version 2005 and above, you can use
RANK() OVER ( PARTITION BY DocNumber ORDER BY ID ASC) AS RevOrder

I think a row_number() function with partition by clause will work
declare #temp as table(
ID int not null
,Doc_Num varchar(20) not null
,RevOrder int null
)
insert into #temp
values
(1,'DOC-001',null)
,(2,'DOC-001',null)
,(3,'DOC-001',null)
,(4,'DOC-002',null)
,(5,'DOC-002',null)
,(6,'DOC-003',null)
select * from #temp
select
t.ID
,t.Doc_Num
,ROW_NUMBER() over(partition by t.Doc_num order by t.ID desc)
from
#temp t
order by t.ID

Use ROW_NUMBER() & PARTITION BY
SELECT ID,
DocNumber,
ROW_NUMBER() OVER(PARTITION BY DocNumber ORDER BY DocNumber DESC) AS RevOrder
FROM #TestTable
You can view/test a working example here: https://data.stackexchange.com/stackoverflow/q/116435/

Related

Find the Contents of a row by provided Row Number? [duplicate]

I found one question answered with the Row_Number() function in the where clause. When I tried one query, I was getting the following error:
"Msg 4108, Level 15, State 1, Line 1
Windowed functions can only appear in the SELECT or ORDER BY clauses."
Here is the query I tried. If somebody knows how to solve this, please let me know.
SELECT employee_id
FROM V_EMPLOYEE
WHERE row_number() OVER ( ORDER BY employee_id ) > 0
ORDER BY Employee_ID
To get around this issue, wrap your select statement in a CTE, and then you can query against the CTE and use the windowed function's results in the where clause.
WITH MyCte AS
(
select employee_id,
RowNum = row_number() OVER ( order by employee_id )
from V_EMPLOYEE
ORDER BY Employee_ID
)
SELECT employee_id
FROM MyCte
WHERE RowNum > 0
SELECT employee_id
FROM (
SELECT employee_id, ROW_NUMBER() OVER (ORDER BY employee_id) AS rn
FROM V_EMPLOYEE
) q
WHERE rn > 0
ORDER BY
Employee_ID
Note that this filter is redundant: ROW_NUMBER() starts from 1 and is always greater than 0.
Select * from
(
Select ROW_NUMBER() OVER ( order by Id) as 'Row_Number', *
from tbl_Contact_Us
) as tbl
Where tbl.Row_Number = 5
I think you want something like this:
SELECT employee_id
FROM (SELECT employee_id, row_number()
OVER (order by employee_id) AS 'rownumber'
FROM V_EMPLOYEE) TableExpressionsMustHaveAnAliasForDumbReasons
WHERE rownumber > 0
In response to comments on rexem's answer, with respect to whether a an inline view or CTE would be faster I recast the queries to use a table I, and everyone, had available: sys.objects.
WITH object_rows AS (
SELECT object_id,
ROW_NUMBER() OVER ( ORDER BY object_id) RN
FROM sys.objects)
SELECT object_id
FROM object_rows
WHERE RN > 1
SELECT object_id
FROM (SELECT object_id,
ROW_NUMBER() OVER ( ORDER BY object_id) RN
FROM sys.objects) T
WHERE RN > 1
The query plans produced were exactly the same. I would expect in all cases, the query optimizer would come up with the same plan, at least in simple replacement of CTE with inline view or vice versa.
Of course, try your own queries on your own system to see if there is a difference.
Also, row_number() in the where clause is a common error in answers given on Stack Overflow. Logicaly row_number() is not available until the select clause is processed. People forget that and when they answer without testing the answer, the answer is sometimes wrong. (A charge I have myself been guilty of.)
I feel like all the answers showing use of a CTE or Sub Query are sufficient fixes for this, but I don't see anyone getting to the heart of why OP has a problem. The reason why what OP suggested doesn't work is due to logical query processing order here:
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE/ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
OFFSET/FETCH
I believe this contributes to the answer greatly, because it explains why issues like this one occur. WHERE is always processed before SELECT making a CTE or Sub Query necessary for many functions. You will see this a lot in SQL Server.
WITH MyCte AS
(
select
employee_id,
RowNum = row_number() OVER (order by employee_id)
from V_EMPLOYEE
)
SELECT employee_id
FROM MyCte
WHERE RowNum > 0
ORDER BY employee_id
Using CTE (SQL Server 2005+):
WITH employee_rows AS (
SELECT t.employee_id,
ROW_NUMBER() OVER ( ORDER BY t.employee_id ) 'rownum'
FROM V_EMPLOYEE t)
SELECT er.employee_id
FROM employee_rows er
WHERE er.rownum > 1
Using Inline view/Non-CTE Equivalent Alternative:
SELECT er.employee_id
FROM (SELECT t.employee_id,
ROW_NUMBER() OVER ( ORDER BY t.employee_id ) 'rownum'
FROM V_EMPLOYEE t) er
WHERE er.rownum > 1
based on OP's answer to question:
Please see this link. Its having a
different solution, which looks
working for the person who asked the
question. I'm trying to figure out a
solution like this.
Paginated query using sorting on different columns using ROW_NUMBER() OVER () in SQL Server 2005
~Joseph
"method 1" is like the OP's query from the linked question, and "method 2" is like the query from the selected answer. You had to look at the code linked in this answer to see what was really going on, since the code in the selected answer was modified to make it work. Try this:
DECLARE #YourTable table (RowID int not null primary key identity, Value1 int, Value2 int, value3 int)
SET NOCOUNT ON
INSERT INTO #YourTable VALUES (1,1,1)
INSERT INTO #YourTable VALUES (1,1,2)
INSERT INTO #YourTable VALUES (1,1,3)
INSERT INTO #YourTable VALUES (1,2,1)
INSERT INTO #YourTable VALUES (1,2,2)
INSERT INTO #YourTable VALUES (1,2,3)
INSERT INTO #YourTable VALUES (1,3,1)
INSERT INTO #YourTable VALUES (1,3,2)
INSERT INTO #YourTable VALUES (1,3,3)
INSERT INTO #YourTable VALUES (2,1,1)
INSERT INTO #YourTable VALUES (2,1,2)
INSERT INTO #YourTable VALUES (2,1,3)
INSERT INTO #YourTable VALUES (2,2,1)
INSERT INTO #YourTable VALUES (2,2,2)
INSERT INTO #YourTable VALUES (2,2,3)
INSERT INTO #YourTable VALUES (2,3,1)
INSERT INTO #YourTable VALUES (2,3,2)
INSERT INTO #YourTable VALUES (2,3,3)
INSERT INTO #YourTable VALUES (3,1,1)
INSERT INTO #YourTable VALUES (3,1,2)
INSERT INTO #YourTable VALUES (3,1,3)
INSERT INTO #YourTable VALUES (3,2,1)
INSERT INTO #YourTable VALUES (3,2,2)
INSERT INTO #YourTable VALUES (3,2,3)
INSERT INTO #YourTable VALUES (3,3,1)
INSERT INTO #YourTable VALUES (3,3,2)
INSERT INTO #YourTable VALUES (3,3,3)
SET NOCOUNT OFF
DECLARE #PageNumber int
DECLARE #PageSize int
DECLARE #SortBy int
SET #PageNumber=3
SET #PageSize=5
SET #SortBy=1
--SELECT * FROM #YourTable
--Method 1
;WITH PaginatedYourTable AS (
SELECT
RowID,Value1,Value2,Value3
,CASE #SortBy
WHEN 1 THEN ROW_NUMBER() OVER (ORDER BY Value1 ASC)
WHEN 2 THEN ROW_NUMBER() OVER (ORDER BY Value2 ASC)
WHEN 3 THEN ROW_NUMBER() OVER (ORDER BY Value3 ASC)
WHEN -1 THEN ROW_NUMBER() OVER (ORDER BY Value1 DESC)
WHEN -2 THEN ROW_NUMBER() OVER (ORDER BY Value2 DESC)
WHEN -3 THEN ROW_NUMBER() OVER (ORDER BY Value3 DESC)
END AS RowNumber
FROM #YourTable
--WHERE
)
SELECT
RowID,Value1,Value2,Value3,RowNumber
,#PageNumber AS PageNumber, #PageSize AS PageSize, #SortBy AS SortBy
FROM PaginatedYourTable
WHERE RowNumber>=(#PageNumber-1)*#PageSize AND RowNumber<=(#PageNumber*#PageSize)-1
ORDER BY RowNumber
--------------------------------------------
--Method 2
;WITH PaginatedYourTable AS (
SELECT
RowID,Value1,Value2,Value3
,ROW_NUMBER() OVER
(
ORDER BY
CASE #SortBy
WHEN 1 THEN Value1
WHEN 2 THEN Value2
WHEN 3 THEN Value3
END ASC
,CASE #SortBy
WHEN -1 THEN Value1
WHEN -2 THEN Value2
WHEN -3 THEN Value3
END DESC
) RowNumber
FROM #YourTable
--WHERE more conditions here
)
SELECT
RowID,Value1,Value2,Value3,RowNumber
,#PageNumber AS PageNumber, #PageSize AS PageSize, #SortBy AS SortBy
FROM PaginatedYourTable
WHERE
RowNumber>=(#PageNumber-1)*#PageSize AND RowNumber<=(#PageNumber*#PageSize)-1
--AND more conditions here
ORDER BY
CASE #SortBy
WHEN 1 THEN Value1
WHEN 2 THEN Value2
WHEN 3 THEN Value3
END ASC
,CASE #SortBy
WHEN -1 THEN Value1
WHEN -2 THEN Value2
WHEN -3 THEN Value3
END DESC
OUTPUT:
RowID Value1 Value2 Value3 RowNumber PageNumber PageSize SortBy
------ ------ ------ ------ ---------- ----------- ----------- -----------
10 2 1 1 10 3 5 1
11 2 1 2 11 3 5 1
12 2 1 3 12 3 5 1
13 2 2 1 13 3 5 1
14 2 2 2 14 3 5 1
(5 row(s) affected
RowID Value1 Value2 Value3 RowNumber PageNumber PageSize SortBy
------ ------ ------ ------ ---------- ----------- ----------- -----------
10 2 1 1 10 3 5 1
11 2 1 2 11 3 5 1
12 2 1 3 12 3 5 1
13 2 2 1 13 3 5 1
14 2 2 2 14 3 5 1
(5 row(s) affected)
select salary from (
select Salary, ROW_NUMBER() over (order by Salary desc) rn from Employee
) t where t.rn = 2

Delete all the rows from table A under each Name who's ID is less then highest ID

create Table A
(
ID Int,
Name Varchar(10)
)
Insert Into A Values(1,'A'),
(1,'B'),
(2,'A'),
(3,'A'),
(3,'C'),
(2,'B'),
(2,'C'),
(1,'C'),
(4,'C'),
(4,'B')
SELECT * FROM A ORDER BY NAME,ID
Result:
ID Name
1 A
2 A
3 A
1 B
2 B
4 B
1 C
2 C
3 C
4 C
If I run this below query:
;WITH CTETEST
AS
(
SELECT MAX(ID)[MAXID],Name FROM A GROUP BY NAME
)
SELECT max([MAXID])[ID],A.Name FROM CTETEST
join A
on A.ID=CTETEST.MAXID
GROUP BY A.NAME
Result:
ID Name
3 A
4 B
4 C
I want this above result set in the main base table and delete rest which is less then the highest ID under each Name category. Please suggest me some query.
I would use an updatable CTE in SQL Server:
with todelete as (
select a.*, max(id) over (partition by name) as maxid
from a
)
delete todelete from todelete
where id < maxid;
In almost any database, you can use:
delete a
where id < (select max(id) from a a2 where a2.name = a.name);
You can try to delete by CTE, make row number by Name order by ID desc in CTE.
Then only keep rn = 1 row datas.
;with cte as(
SELECT *,ROW_NUMBER() OVER(PARTITION BY Name ORDER BY ID desc) rn FROM A
)
delete cte
where rn > 1
sqlfiddle

SQL Row_Number() increase only when the value = 1 for a specific column

I am having some trouble generating row_number() in my SQL query as my expectation. I have this following output of my query-
Now, I want to add row number for all rows where row number will only increase when the value in C1 is = 1. Required output as below-
Any help will be appreciated. TIA
Table Variable:
DECLARE #Table AS TABLE (C1 INT)
INSERT INTO #Table VALUES (1),(4),(1),(1),(4),(1),(3),(4)
SQL 2008 Version
;WITH cteSimulateAnOriginalIdentityKey AS (
SELECT
C1
,OriginalOrder = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM
#Table
)
, cteC1RowNumber AS (
SELECT
*
,C1RowNumber = ROW_NUMBER() OVER (PARTITION BY C1 ORDER BY OriginalOrder)
FROM
cteSimulateAnOriginalIdentityKey
)
SELECT
C1
,RN = ISNULL((SELECT MAX(C1RowNumber) FROM cteC1RowNumber r2 WHERE r2.C1 = 1 AND r2.OriginalOrder <= r1.OriginalOrder),1)
FROM
cteC1RowNumber r1
ORDER BY
OriginalOrder
SQL 2012+ version
;WITH cteSimulateAnOriginalIdentityKey AS (
SELECT
C1
,OriginalOrder = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM
#Table
)
, cteC1RowNumber AS (
SELECT
*
,C1RowNumber = ROW_NUMBER() OVER (PARTITION BY C1 ORDER BY OriginalOrder)
FROM
cteSimulateAnOriginalIdentityKey
)
SELECT
C1
,RN = ISNULL(MAX(CASE WHEN C1 = 1 THEN C1RowNumber END) OVER (ORDER BY OriginalOrder),1)
FROM
cteC1RowNumber
ORDER BY
OriginalOrder
RESULT:
C1 RN
1 1
4 1
1 2
1 3
4 3
1 4
3 4
4 4
If you in fact have another column by which to maintain the desired original order you don't need the first cte which is simply simulating that column
Try this:
SELECT C1,
ROW_NUMBER() OVER (PARTITION BY C1 ORDER BY (SELECT 100)) RN
FROM TableNAme
I presume you have another column(s) in your query by which you determine the order of rows; without such a criteria, your whole question is pointless.
The query below will work on SQL Server 2012 or later versions:
declare #Table table (
Id int identity(1,1) not null,
C1 int
);
insert into #Table(C1) values (1),(4),(1),(1),(4),(1),(3),(4);
select t.C1,
sum(case t.C1 when 1 then 1 else 0 end) over(order by t.Id) as [RN]
from #Table t;

SQL cross apply

I have a SQL table which contains audit information:
GroupId AuditDate ID FirstName LastName
1 01/06/2011 123 Michael Jackson
1 01/09/2010 123 M J
1 01/06/2009 123 Mike J
and trying show the differences between the audit records:
GroupId AuditDate ID Attribute From To
1 01/06/2011 123 FirstName M Michael
1 01/06/2011 123 LastName J Jackson
1 01/09/2010 123 FirstName Mike M
1 01/06/2009 123 FirstName NULL Mike
1 01/06/2009 123 LastName NULL J
I am using the following SQL query:
WITH result AS (
SELECT [Current].Id,
[Current].GroupId,
[Current].AuditDate,
[Current].FirstName,
[Current].LastName
Previous.FirstName AS PFirstName,
Previous.LastName AS PLastName,
FROM
(SELECT
*, ROW_NUMBER() OVER(PARTITION BY GroupId ORDER BY AuditDate ASC) AS RowNumber
FROM
AuditTable
WHERE
Id = #ID
) AS [Current]
LEFT JOIN
(SELECT
*, ROW_NUMBER() OVER(PARTITION BY GroupId ORDER BY AuditDate ASC) AS RowNumber
FROM
AuditTable
WHERE
Id = #ID
) AS [Previous]
ON
[Current].RowNumber = [Previous].RowNumber + 1
)
SELECT r.Id,r.GroupId, r.AuditDate
x.Attribute,
x.[From],
x.[To]
FROM result r
CROSS APPLY
(
VALUES
('FirstName', t.FirstName, t.PFirstName),
('LastName', t.LastName, t.PLastName),
) x (Attribute, [To], [From])
where
ISNULL(x.[From],'') <> ISNULL(x.[To],'')
ORDER BY r.AuditDate asc;
Is it possible to merge two select queries to improve the performance?
Try this query
WITH result AS (
SELECT Id,
GroupId,
AuditDate,
FirstName,
LastName,
ROW_NUMBER() OVER(PARTITION BY GroupId ORDER BY AuditDate ASC) AS RowNumber
FROM AuditTable
WHERE Id = #ID
)
SELECT r.Id,r.GroupId, r.AuditDate,
x.Attribute,
x.[From],
x.[To]
FROM result r LEFT JOIN result r2 ON r.RowNumber = r2.RowNumber + 1
CROSS APPLY (
VALUES ('FirstName', r.FirstName, r2.FirstName),
('LastName', r.LastName, r2.LastName)
) x (Attribute, [To], [From])
WHERE ISNULL(x.[From],'') <> ISNULL(x.[To],'')
ORDER BY r.AuditDate ASC;
Demo on SQLFiddle
You can eliminate both subqueries entirely by using lag():
WITH result AS (
SELECT Id,
GroupId,
AuditDate,
FirstName,
LastName,
lag(FirstName) over (PARTITION BY GroupId ORDER BY AuditDate ASC)
AS PFirstName,
lag(LastName) over (PARTITION BY GroupId ORDER BY AuditDate ASC)
AS PLastName
FROM AuditTable
WHERE Id = #ID
)
...
Here is the relevant documentation.
Update: However, this is only available in SQL Server 2012, unfortunately. If you have an earlier version, you will need some sort of self join.
If you can't use lag(), you should at least be able to reduce your code from 3 queries to 2: include the row number in your first select statement, and left join one subquery to it rather than having two subqueries. I'm not sure whether this way or Chris Moutray's way would be faster.
WITH result AS (
SELECT ROW_NUMBER() OVER(PARTITION BY GroupId ORDER BY AuditDate ASC) AS RowNumber
[Current].Id,
[Current].GroupId,
[Current].AuditDate,
[Current].FirstName,
[Current].LastName
[Previous].FirstName AS PFirstName,
[Previous].LastName AS PLastName,
FROM AuditTable as [Current]
LEFT JOIN
(SELECT
*, ROW_NUMBER() OVER(PARTITION BY GroupId ORDER BY AuditDate ASC) AS RowNumber
FROM
AuditTable
WHERE
Id = #ID
) AS [Previous]
ON
[Current].RowNumber = [Previous].RowNumber + 1
)
You can use LAG in SQL Server 2012. I've used UNION ALL here to unpivot columns into rows.
Depending on how you filter and what your group level is, add/modify the PARTITION BY
DECLARE #foo TABLE (GroupId tinyint, AuditDate date, ID tinyint, FirstName varchar(100), LastName varchar(100));
INSERT #foo VALUES (1, '20110601', 123, 'Michael', 'Jackson'), (1, '20100901', 123, 'M', 'J'), (1, '20090601', 123, 'Mike', 'J');
SELECT
X.GroupId, X.AuditDate, X.ID, X.[From], X.[To]
FROM
(
SELECT
F.GroupId, F.AuditDate, F.ID, 'FirstName' AS Attribute, LAG(F.FirstName) OVER (/*PARTITION BY GroupId, ID*/ ORDER BY AuditDate) AS [From], F.FirstName AS [To]
FROM
#foo F
UNION ALL
SELECT
F.GroupId, F.AuditDate, F.ID, 'LastName' AS Attribute, LAG(F.LastName) OVER (/*PARTITION BY GroupId, ID*/ ORDER BY AuditDate) AS [From], F.LastName AS [To]
FROM
#foo F
) X
WHERE
ISNULL(X.[From], '') <> ISNULL(X.[To], '')
ORDER BY
X.AuditDate DESC, X.Attribute

SQL Row_Number() function in Where Clause

I found one question answered with the Row_Number() function in the where clause. When I tried one query, I was getting the following error:
"Msg 4108, Level 15, State 1, Line 1
Windowed functions can only appear in the SELECT or ORDER BY clauses."
Here is the query I tried. If somebody knows how to solve this, please let me know.
SELECT employee_id
FROM V_EMPLOYEE
WHERE row_number() OVER ( ORDER BY employee_id ) > 0
ORDER BY Employee_ID
To get around this issue, wrap your select statement in a CTE, and then you can query against the CTE and use the windowed function's results in the where clause.
WITH MyCte AS
(
select employee_id,
RowNum = row_number() OVER ( order by employee_id )
from V_EMPLOYEE
ORDER BY Employee_ID
)
SELECT employee_id
FROM MyCte
WHERE RowNum > 0
SELECT employee_id
FROM (
SELECT employee_id, ROW_NUMBER() OVER (ORDER BY employee_id) AS rn
FROM V_EMPLOYEE
) q
WHERE rn > 0
ORDER BY
Employee_ID
Note that this filter is redundant: ROW_NUMBER() starts from 1 and is always greater than 0.
Select * from
(
Select ROW_NUMBER() OVER ( order by Id) as 'Row_Number', *
from tbl_Contact_Us
) as tbl
Where tbl.Row_Number = 5
I think you want something like this:
SELECT employee_id
FROM (SELECT employee_id, row_number()
OVER (order by employee_id) AS 'rownumber'
FROM V_EMPLOYEE) TableExpressionsMustHaveAnAliasForDumbReasons
WHERE rownumber > 0
In response to comments on rexem's answer, with respect to whether a an inline view or CTE would be faster I recast the queries to use a table I, and everyone, had available: sys.objects.
WITH object_rows AS (
SELECT object_id,
ROW_NUMBER() OVER ( ORDER BY object_id) RN
FROM sys.objects)
SELECT object_id
FROM object_rows
WHERE RN > 1
SELECT object_id
FROM (SELECT object_id,
ROW_NUMBER() OVER ( ORDER BY object_id) RN
FROM sys.objects) T
WHERE RN > 1
The query plans produced were exactly the same. I would expect in all cases, the query optimizer would come up with the same plan, at least in simple replacement of CTE with inline view or vice versa.
Of course, try your own queries on your own system to see if there is a difference.
Also, row_number() in the where clause is a common error in answers given on Stack Overflow. Logicaly row_number() is not available until the select clause is processed. People forget that and when they answer without testing the answer, the answer is sometimes wrong. (A charge I have myself been guilty of.)
I feel like all the answers showing use of a CTE or Sub Query are sufficient fixes for this, but I don't see anyone getting to the heart of why OP has a problem. The reason why what OP suggested doesn't work is due to logical query processing order here:
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE/ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
OFFSET/FETCH
I believe this contributes to the answer greatly, because it explains why issues like this one occur. WHERE is always processed before SELECT making a CTE or Sub Query necessary for many functions. You will see this a lot in SQL Server.
WITH MyCte AS
(
select
employee_id,
RowNum = row_number() OVER (order by employee_id)
from V_EMPLOYEE
)
SELECT employee_id
FROM MyCte
WHERE RowNum > 0
ORDER BY employee_id
Using CTE (SQL Server 2005+):
WITH employee_rows AS (
SELECT t.employee_id,
ROW_NUMBER() OVER ( ORDER BY t.employee_id ) 'rownum'
FROM V_EMPLOYEE t)
SELECT er.employee_id
FROM employee_rows er
WHERE er.rownum > 1
Using Inline view/Non-CTE Equivalent Alternative:
SELECT er.employee_id
FROM (SELECT t.employee_id,
ROW_NUMBER() OVER ( ORDER BY t.employee_id ) 'rownum'
FROM V_EMPLOYEE t) er
WHERE er.rownum > 1
based on OP's answer to question:
Please see this link. Its having a
different solution, which looks
working for the person who asked the
question. I'm trying to figure out a
solution like this.
Paginated query using sorting on different columns using ROW_NUMBER() OVER () in SQL Server 2005
~Joseph
"method 1" is like the OP's query from the linked question, and "method 2" is like the query from the selected answer. You had to look at the code linked in this answer to see what was really going on, since the code in the selected answer was modified to make it work. Try this:
DECLARE #YourTable table (RowID int not null primary key identity, Value1 int, Value2 int, value3 int)
SET NOCOUNT ON
INSERT INTO #YourTable VALUES (1,1,1)
INSERT INTO #YourTable VALUES (1,1,2)
INSERT INTO #YourTable VALUES (1,1,3)
INSERT INTO #YourTable VALUES (1,2,1)
INSERT INTO #YourTable VALUES (1,2,2)
INSERT INTO #YourTable VALUES (1,2,3)
INSERT INTO #YourTable VALUES (1,3,1)
INSERT INTO #YourTable VALUES (1,3,2)
INSERT INTO #YourTable VALUES (1,3,3)
INSERT INTO #YourTable VALUES (2,1,1)
INSERT INTO #YourTable VALUES (2,1,2)
INSERT INTO #YourTable VALUES (2,1,3)
INSERT INTO #YourTable VALUES (2,2,1)
INSERT INTO #YourTable VALUES (2,2,2)
INSERT INTO #YourTable VALUES (2,2,3)
INSERT INTO #YourTable VALUES (2,3,1)
INSERT INTO #YourTable VALUES (2,3,2)
INSERT INTO #YourTable VALUES (2,3,3)
INSERT INTO #YourTable VALUES (3,1,1)
INSERT INTO #YourTable VALUES (3,1,2)
INSERT INTO #YourTable VALUES (3,1,3)
INSERT INTO #YourTable VALUES (3,2,1)
INSERT INTO #YourTable VALUES (3,2,2)
INSERT INTO #YourTable VALUES (3,2,3)
INSERT INTO #YourTable VALUES (3,3,1)
INSERT INTO #YourTable VALUES (3,3,2)
INSERT INTO #YourTable VALUES (3,3,3)
SET NOCOUNT OFF
DECLARE #PageNumber int
DECLARE #PageSize int
DECLARE #SortBy int
SET #PageNumber=3
SET #PageSize=5
SET #SortBy=1
--SELECT * FROM #YourTable
--Method 1
;WITH PaginatedYourTable AS (
SELECT
RowID,Value1,Value2,Value3
,CASE #SortBy
WHEN 1 THEN ROW_NUMBER() OVER (ORDER BY Value1 ASC)
WHEN 2 THEN ROW_NUMBER() OVER (ORDER BY Value2 ASC)
WHEN 3 THEN ROW_NUMBER() OVER (ORDER BY Value3 ASC)
WHEN -1 THEN ROW_NUMBER() OVER (ORDER BY Value1 DESC)
WHEN -2 THEN ROW_NUMBER() OVER (ORDER BY Value2 DESC)
WHEN -3 THEN ROW_NUMBER() OVER (ORDER BY Value3 DESC)
END AS RowNumber
FROM #YourTable
--WHERE
)
SELECT
RowID,Value1,Value2,Value3,RowNumber
,#PageNumber AS PageNumber, #PageSize AS PageSize, #SortBy AS SortBy
FROM PaginatedYourTable
WHERE RowNumber>=(#PageNumber-1)*#PageSize AND RowNumber<=(#PageNumber*#PageSize)-1
ORDER BY RowNumber
--------------------------------------------
--Method 2
;WITH PaginatedYourTable AS (
SELECT
RowID,Value1,Value2,Value3
,ROW_NUMBER() OVER
(
ORDER BY
CASE #SortBy
WHEN 1 THEN Value1
WHEN 2 THEN Value2
WHEN 3 THEN Value3
END ASC
,CASE #SortBy
WHEN -1 THEN Value1
WHEN -2 THEN Value2
WHEN -3 THEN Value3
END DESC
) RowNumber
FROM #YourTable
--WHERE more conditions here
)
SELECT
RowID,Value1,Value2,Value3,RowNumber
,#PageNumber AS PageNumber, #PageSize AS PageSize, #SortBy AS SortBy
FROM PaginatedYourTable
WHERE
RowNumber>=(#PageNumber-1)*#PageSize AND RowNumber<=(#PageNumber*#PageSize)-1
--AND more conditions here
ORDER BY
CASE #SortBy
WHEN 1 THEN Value1
WHEN 2 THEN Value2
WHEN 3 THEN Value3
END ASC
,CASE #SortBy
WHEN -1 THEN Value1
WHEN -2 THEN Value2
WHEN -3 THEN Value3
END DESC
OUTPUT:
RowID Value1 Value2 Value3 RowNumber PageNumber PageSize SortBy
------ ------ ------ ------ ---------- ----------- ----------- -----------
10 2 1 1 10 3 5 1
11 2 1 2 11 3 5 1
12 2 1 3 12 3 5 1
13 2 2 1 13 3 5 1
14 2 2 2 14 3 5 1
(5 row(s) affected
RowID Value1 Value2 Value3 RowNumber PageNumber PageSize SortBy
------ ------ ------ ------ ---------- ----------- ----------- -----------
10 2 1 1 10 3 5 1
11 2 1 2 11 3 5 1
12 2 1 3 12 3 5 1
13 2 2 1 13 3 5 1
14 2 2 2 14 3 5 1
(5 row(s) affected)
select salary from (
select Salary, ROW_NUMBER() over (order by Salary desc) rn from Employee
) t where t.rn = 2