Jac*_*ack 6 sql t-sql sql-server sql-server-2008
说我有这些行,
InstrumentID
547
698
708
Run Code Online (Sandbox Code Playgroud)
InstrumentID不是自动生成的列.
假如我在程序中传递参数为698,我应该将之前的值设为547,将下一个值设为708.如何在SQL中有效地执行此操作?
我有这个程序,但效率不高(而且不正确).
Alter PROCEDURE GetNextAndPreviousInsturmentID
(
@InstrumentID varchar(14),
@PreviousInstrumentID varchar(14) OUT,
@NextInstrumentID varchar(14) OUT
)
AS
BEGIN
Declare @RowNum int = 0
Select @RowNum = ROW_NUMBER() Over (Order by Cast(@InstrumentID as decimal(18))) From Documents Where InstrumentID = @InstrumentID
;With normal As
(
Select ROW_NUMBER() Over (Order by Cast(@InstrumentID as decimal(18))) as RowNum, Cast(InstrumentID as decimal(18)) as InstrumentID
From Documents
)
Select @PreviousInstrumentID = InstrumentID From normal
Where RowNum = @RowNum - 1
Select @NextInstrumentID = InstrumentID From normal
Where RowNum = @RowNum + 1
END
GO
Run Code Online (Sandbox Code Playgroud)
Igo*_*nko 11
这是一个更简单的解决方案,但仍然更有效
SELECT P.PreviousID, N.NextID
FROM
(SELECT MAX(D.InstrumentID) PreviousID
FROM Documents D
WHERE InstrumentID < @InstrumentID) P
CROSS JOIN
(SELECT MIN(D.InstrumentID) NextID
FROM Documents D
WHERE InstrumentID > @InstrumentID) N
Run Code Online (Sandbox Code Playgroud)
尝试这个:
Alter PROCEDURE GetNextAndPreviousInsturmentID
(
@InstrumentID varchar(14),
@PreviousInstrumentID varchar(14) OUT,
@NextInstrumentID varchar(14) OUT
)
AS
BEGIN
Declare @Ids TABLE(Id varchar(14))
;With normal As
(
--Numerate our rows
Select ROW_NUMBER() Over (Order by Cast(Documents.InstrumentID as decimal(18)) as RowNumber,
Documents.InstrumentID
From Documents
)
--Insert three rows from our table with our id and previos/next id
INSERT INTO @Ids(Id)
SELECT TOP(3) normal.InstrumentID
FROM normal
WHERE RowNumber >=
(
SELECT RowNumber - 1
FROM normal
WHERE normal.InstrumentID = @InstrumentID
)
ORDER BY normal.RowNumber
--select next and previos ids
SELECT @PreviousInstrumentID = Min(CAST(Id as decimal(18))),
@NextInstrumentID = MAX(CAST(Id as decimal(18)))
FROM @Ids
END
GO
Run Code Online (Sandbox Code Playgroud)
在 MS SQL 2012 中,我们有新的窗口函数,如 FIRST_VALUE 和 LAST_VALUE,不幸的是在 sql 2008 中这些函数丢失了。