6

これらの行があるとしましょう、

InstrumentID

547
698
708

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
4

5 に答える 5

12

これはより単純な解決策ですが、それでもより効率的です

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
于 2013-02-19T08:21:07.773 に答える
2

これを試して:

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

MS SQL 2012には、FIRST_VALUEやLAST_VALUEなどの新しいウィンドウ関数がありますが、残念ながらsql2008ではこれらの関数がありません。

于 2013-02-19T07:17:03.847 に答える
0
WITH CTE AS (
  SELECT rownum = ROW_NUMBER() OVER (ORDER BY p.LogDate), p.LogDate
  FROM DeviceLogs p
)
SELECT prev.logdate PreviousValue, CTE.logdate, nex.logdate NextValue
FROM CTE
LEFT JOIN CTE prev ON prev.rownum = CTE.rownum - 1
LEFT JOIN CTE nex ON nex.rownum = CTE.rownum + 1

GO
于 2015-01-17T12:05:24.990 に答える
-1

こんにちは私はこれがはるかに効率的だと思います:

次を選択:

select top 1 ID from mytable
where ID >'698'
order by ID asc

前を選択:

select top 1 ID from mytable
where ID <'698'
order by ID desc
于 2014-07-05T11:29:46.050 に答える
-1

選択する

LAG(InstrumentID) OVER (ORDER BY InstrumentID) PreviousValue,
InstrumentID, 
LEAD(InstrumentID) OVER (ORDER BY InstrumentID) NextValue
from documents
于 2016-09-21T14:24:45.593 に答える