3

我有一组带有 a 的数据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--
4

4 回答 4

3

如果您想在前后获得 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

编辑:

从问题的上下文中我不清楚是否真的需要行号。虽然很容易添加:

(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;

您可以将其放在子查询中并选择rn-50 到 50 之间的位置。

但是,我不确定如何处理第 0 行,并且该问题没有提供有关如何处理任何匹配的记录的信息getdate()(尽管不太可能)。我认为第一个答案可以满足 OP 的需要。

于 2014-04-25T11:52:03.773 回答
1

您可以使用两个 CTE,一个用于过去的日期,一个用于未来的日期,然后使用ROW_NUMBERwith ASCand ,将 before now 与 concat allDESC相乘:-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
于 2014-04-25T11:56:55.017 回答
0

试试这个...

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
于 2014-04-25T11:58:14.667 回答
0

带行号

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
于 2014-04-25T12:10:22.273 回答