简体   繁体   English

如何在sql server中获得负rownumber

[英]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_NUMBERASCDESC ,在此之前乘以-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM