我正在查询我需要下一行的第n行。我的表结构就像
ID StockName StockDate DayOpen DayHigh DayLow DayClose
--------------------------------------------------------------------
60 IDBI 2014-01-01 66.50 67.80 66.50 67.60
197 IDBI 2014-01-02 67.55 69.20 65.25 65.60
334 IDBI 2014-01-03 65.00 66.40 64.35 66.15
471 IDBI 2014-01-06 66.15 66.35 65.10 65.55
608 IDBI 2014-01-07 66.10 66.15 63.85 64.25
745 IDBI 2014-01-08 64.00 67.10 63.10 66.80
882 IDBI 2014-01-09 66.60 67.80 64.50 64.75
1019 IDBI 2014-01-10 65.00 65.90 63.75 64.10
1156 IDBI 2014-01-13 63.85 65.00 63.25 64.20
1293 IDBI 2014-01-14 64.00 64.95 63.80 64.05
我想要输出的是列名,它将为我提供下一个第5行日期
E.g。对于第1行,新列应该返回下一个第5行日期的值,即2014-01-08
对于第2行应该返回2014-01-09
日期。
由于这些是工作日数据,不包括周末,我无法使用datediff
-5天计数
如何在不使用while循环或游标的情况下获取此值?
答案 0 :(得分:3)
使用CTE返回基表加上ROW_NUMBER,以便您可以在新[Next5thDate]列的ROW_NUMBER上将CTE LEFT JOIN连接到当前行的前5行:
SET NOCOUNT ON;
SET ANSI_NULLS ON;
DECLARE @Data TABLE (
ID INT NOT NULL PRIMARY KEY CLUSTERED,
StockName VARCHAR(50) NOT NULL,
StockDate DATE NOT NULL,
DayOpen MONEY NOT NULL,
DayHigh MONEY NOT NULL,
DayLow MONEY NOT NULL,
DayClose MONEY NOT NULL,
UNIQUE(StockDate)
)
INSERT INTO @Data VALUES (60, 'IDBI', '2014-01-01', 66.50, 67.80, 66.50, 67.60)
INSERT INTO @Data VALUES (197, 'IDBI', '2014-01-02', 67.55, 69.20, 65.25, 65.60)
INSERT INTO @Data VALUES (334, 'IDBI', '2014-01-03', 65.00, 66.40, 64.35, 66.15)
INSERT INTO @Data VALUES (471, 'IDBI', '2014-01-06', 66.15, 66.35, 65.10, 65.55)
INSERT INTO @Data VALUES (608, 'IDBI', '2014-01-07', 66.10, 66.15, 63.85, 64.25)
INSERT INTO @Data VALUES (745, 'IDBI', '2014-01-08', 64.00, 67.10, 63.10, 66.80)
INSERT INTO @Data VALUES (882, 'IDBI', '2014-01-09', 66.60, 67.80, 64.50, 64.75)
INSERT INTO @Data VALUES (1019, 'IDBI', '2014-01-10', 65.00, 65.90, 63.75, 64.10)
INSERT INTO @Data VALUES (1156, 'IDBI', '2014-01-13', 63.85, 65.00, 63.25, 64.20)
INSERT INTO @Data VALUES (1293, 'IDBI', '2014-01-14', 64.00, 64.95, 63.80, 64.05)
;WITH cte AS
(
SELECT d.*, ROW_NUMBER() OVER (ORDER BY d.StockDate ASC) AS [RowNum]
FROM @Data d
)
SELECT d1.ID, d1.StockName, d1.StockDate, d1.DayOpen, d1.DayHigh,
d1.DayLow, d1.DayClose, d2.StockDate AS [Next5thDate]
FROM cte d1
LEFT JOIN cte d2
ON d2.RowNum = (d1.RowNum + 5)
结果:
ID StockName StockDate DayOpen DayHigh DayLow DayClose Next5thDate
60 IDBI 2014-01-01 66.50 67.80 66.50 67.60 2014-01-08
197 IDBI 2014-01-02 67.55 69.20 65.25 65.60 2014-01-09
334 IDBI 2014-01-03 65.00 66.40 64.35 66.15 2014-01-10
471 IDBI 2014-01-06 66.15 66.35 65.10 65.55 2014-01-13
608 IDBI 2014-01-07 66.10 66.15 63.85 64.25 2014-01-14
745 IDBI 2014-01-08 64.00 67.10 63.10 66.80 NULL
882 IDBI 2014-01-09 66.60 67.80 64.50 64.75 NULL
1019 IDBI 2014-01-10 65.00 65.90 63.75 64.10 NULL
1156 IDBI 2014-01-13 63.85 65.00 63.25 64.20 NULL
1293 IDBI 2014-01-14 64.00 64.95 63.80 64.05 NULL
答案 1 :(得分:1)
With RnkedItems As
(
Select Id, StockName, StockDate, DayOpen, DayHigh, DayLow, DayClose
, Row_Number() Over ( Order By StockDate, Id ) As Rnk
From MyTable
)
Select ...
From RnkedItems As Original
Left Join RnkedItems
On RnkedItems.Rnk = Original.Rnk + 5
我假设你想要在同一行的目标行之后返回目标行和第五行。
答案 2 :(得分:0)
试试这个:
;with EnumeratedStocks as (
select rn = row_number() over(order by StockDate), *
from Stocks
)
select * from EnumeratedStocks es where rn > 5
答案 3 :(得分:0)
您可以在周末提取下一个日期的第5个日期,方法是将日期从下一个第5天开始提取,如果是星期六,则将日期减去两天以上,如果是星期日,则可以延长一天。
Select * , Case DAYNAME( dateadd(day,5,stockdate))
When 'Saturday' Then dateadd(day,7,stockdate)
When 'Sunday' Then dateadd(day,6,stockdate)
Else dateadd(day,6,stockdate) End As newStockDate
From tableName