[英]How to get a negative rownumber in sql server
I have a set of data with a DateTime
, say CalculatedOn
what I would like is to get start at the current date getdate()
and get an x
amount of records from before the current date, and the same amount from after. 我有一组带有
DateTime
的数据,比如说CalculatedOn
我想要的是从当前日期getdate()
开始,并获得当前日期之前的x
量记录,以及之后的相同数量。
If x = 50
then 50 prior to now and 50 in front of now. 如果
x = 50
那么现在前50,现在前50。 I was thinking rownumber()
would be perfect for this, however I cannot think of how to number the rows negative for prior and positive for future. 我当时认为
rownumber()
对于这个来说是完美的,但是我想不出如何将前面的行数为负数而将来为正数。
Also there is the issue of if there are not 50 prior or future what will happen, but that will come after. 还有一个问题是,如果没有50个先前或将来会发生什么,但那将会发生。
Assume the table has just two columns : 假设该表只有两列:
create table MyTable
(
Id int not null constraint pk_mytable primary key,
SomeTextIWant nvarchar(50) not null,
CalculateDate DateTime not null
);
Results : 结果:
If today is 25/04 12:54 如果今天是25/04 12:54
then 然后
Id, SomeTextIWant, CalculatedDate
-- 50 from before now--
-----now here-----
-- 50 from after now--
If you want to get 50 rows before and after, perhaps this will do what you want: 如果你想在之前和之后获得50行,也许这会做你想要的:
with cte1 as (
select top 50 t.*
from table t
where CalculatedDate <= getdate()
order by CalculatedDate desc
),
cte2 as (
select top 50 t.*
from table t
where CalculatedDate > getdate()
order by CalculatedDate
)
select *
from (select * from cte1 union all select * from cte2) t
EDIT: 编辑:
It is not clear to me from the context of the question whether a row number is actually needed. 从问题的上下文中我不清楚是否确实需要行号。 It is easy enough to add, thoug:
很容易添加,thoug:
(select top 50 t.*,
- row_number() over (order by CalculatedDate desc) as rownumber
from table t
where CalculatedDate <= getdate()
order by CalculatedDate desc
)
union all
(select top 50 t.*,
row_number() over (order by CalculatedDate) as rownumber
from table t
where CalculatedDate > getdate()
order by CalculatedDate
)
You can actually combine these into one query: 您实际上可以将这些组合成一个查询:
select t.*,
((case when CalculatedDate < getdate() then -1 else 1 end) *
(row_number() over (partition by (case when CalculatedDate < getdate() then 1 else 0 end)
order by (case when CalculatedDate < getdate() then CalculatedDate end) desc,
CalculatedDate asc
)
)) as rn
from table t;
You can put this in a subquery and select where rn
between -50 and 50. 您可以将其放在子查询中并选择-50到50之间的
rn
。
However, I'm not sure what to do about row number 0 and the question provides no information on what to do with any records that match getdate()
(as unlikely as that is). 但是,我不确定如何处理第0行,并且该问题没有提供有关如何处理与
getdate()
匹配的任何记录的信息(尽管不太可能)。 I think the first answer does what that OP needs. 我认为第一个答案是OP需要的。
You can use two CTE's, one for past and one for future dates, then use ROW_NUMBER
with ASC
and DESC
, multiply before now with -1
and concat all: 您可以使用两个CTE,一个用于过去,一个用于将来的日期,然后将
ROW_NUMBER
与ASC
和DESC
,在此之前乘以-1
并连接所有:
WITH dataBefore AS
(
SELECT d.*, rn = (-1) * row_Number() over (Order By CalculatedOn DESC)
FROM dbo.TableName d
WHERE CalculatedOn < GetDate()
)
, dataAfter AS
(
SELECT d.*, rn = row_Number() over (Order By CalculatedOn ASC)
FROM dbo.TableName d
WHERE CalculatedOn >= GetDate()
)
SELECT * FROM
(
SELECT db.*
FROM dataBefore db
UNION ALL
SELECT da.*
FROM dataAfter da
)x
WHERE x.rn >= -50 AND x.RN <= 50
ORDER BY x.RN
try this... 试试这个...
With myCte
As
(
Select top 2 column1,column2 from YourTable where yourdate > '2014-04-23'
union
Select top 2 column1,column2 from YourTable where yourdate < '2014-04-23'
) select ROW_NUMBER() over (order by column1) as RNO,* from myCte
With RowNumber 使用RowNumber
SELECT TOP 50 ROW_NUMBER() OVER (ORDER BY CalculateDate) AS RowNum,
id, SomeTextIWant, CalculateDate
FROM MyTable
WHERE CalculateDate > @Date
UNION ALL
SELECT TOP 50 -ROW_NUMBER() OVER (ORDER BY CalculateDate DESC) AS RowNum,
id, SomeTextIWant, CalculateDate
FROM MyTable
WHERE CalculateDate < @Date
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.