簡體   English   中英

如何在sql server中獲得負rownumber

[英]How to get a negative rownumber in sql server

我有一組帶有DateTime的數據,比如說CalculatedOn我想要的是從當前日期getdate()開始,並獲得當前日期之前的x量記錄,以及之后的相同數量。

如果x = 50那么現在前50,現在前50。 我當時認為rownumber()對於這個來說是完美的,但是我想不出如何將前面的行數為負數而將來為正數。

還有一個問題是,如果沒有50個先前或將來會發生什么,但那將會發生。

假設該表只有兩列:

create table MyTable
(
   Id int not null constraint pk_mytable primary key,
   SomeTextIWant nvarchar(50) not null,
   CalculateDate DateTime not null
);

結果:

如果今天是25/04 12:54

然后

Id, SomeTextIWant, CalculatedDate
-- 50 from before now--
-----now here-----
-- 50 from after now--

如果你想在之前和之后獲得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

編輯:

從問題的上下文中我不清楚是否確實需要行號。 很容易添加,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
)

您實際上可以將這些組合成一個查詢:

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;

您可以將其放在子查詢中並選擇-50到50之間的rn

但是,我不確定如何處理第0行,並且該問題沒有提供有關如何處理與getdate()匹配的任何記錄的信息(盡管不太可能)。 我認為第一個答案是OP需要的。

您可以使用兩個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

試試這個...

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

使用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