You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL中根据OrderId和ItemId获取指定行的上下行?

获取目标记录上下行及检查同ItemId跨订单存在的SQL解决方案

没问题,我来帮你搞定这个需求!咱们的核心目标是:定位到OrderId=10且ItemId=2的目标记录后,找出所有ItemId=2的记录(按OrderDate排序)中该目标的上一行和下一行,同时验证ItemId=2是否存在于其他订单中。

核心思路

SQL的窗口函数LAG()和LEAD()是处理这类"前后行获取"需求的最优解——它们能在排序后的数据集里,直接提取当前行的前一行、后一行数据。我们的步骤是:先筛选所有ItemId=2的记录并按OrderDate(加Id做稳定排序)排序,标记目标行后,提取它的上下行信息,最后补充跨订单存在性检查。

完整可运行SQL代码

-- 定义表变量并插入测试数据
DECLARE @OderDetail table ( Id int primary key, OrderId int, ItemId int, OrderDate DateTime2, Lookup varchar(15) )
INSERT INTO @OderDetail VALUES 
(1, 10, 1, '2018-06-11', 'A'), 
(2, 10, 2, '2018-06-11', 'BE'), -- 目标行
(3, 2, 1, '2018-06-04', 'DR'), 
(4, 2, 2, '2018-06-04', 'D'), 
(5, 3, 2, '2018-06-14', 'DD'), 
(6, 4, 2, '2018-06-14', 'R');

-- 定义输入参数
DECLARE @ItemId int = 2, @OrderId int = 10;

-- 分步处理的CTE
WITH Item2Records AS (
    -- 筛选所有ItemId=2的记录,计算前后行ID,标记目标行
    SELECT 
        *,
        -- LAG获取上一行ID,LEAD获取下一行ID,加Id确保OrderDate相同时排序稳定
        LAG(Id) OVER (ORDER BY OrderDate, Id) AS PrevRowId,
        LEAD(Id) OVER (ORDER BY OrderDate, Id) AS NextRowId,
        CASE WHEN OrderId = @OrderId AND ItemId = @ItemId THEN 1 ELSE 0 END AS IsTargetRow
    FROM @OderDetail
    WHERE ItemId = @ItemId
),
TargetRowInfo AS (
    -- 提取目标行对应的前后行ID
    SELECT PrevRowId, NextRowId
    FROM Item2Records
    WHERE IsTargetRow = 1
)
-- 合并输出上下行数据+跨订单检查结果
SELECT
    '上一行' AS RowType,
    od.*
FROM @OderDetail od
JOIN TargetRowInfo tri ON od.Id = tri.PrevRowId
UNION ALL
SELECT
    '下一行' AS RowType,
    od.*
FROM @OderDetail od
JOIN TargetRowInfo tri ON od.Id = tri.NextRowId
UNION ALL
-- 输出ItemId=2是否存在于其他订单的检查结果
SELECT
    '跨订单检查' AS RowType,
    NULL AS Id,
    NULL AS OrderId,
    NULL AS ItemId,
    NULL AS OrderDate,
    CASE 
        WHEN EXISTS (SELECT 1 FROM @OderDetail WHERE ItemId = @ItemId AND OrderId != @OrderId) 
        THEN 'ItemId=2存在于其他订单中' 
        ELSE 'ItemId=2仅存在于当前订单' 
    END AS Lookup;

代码细节说明

  1. 稳定排序处理:窗口函数的ORDER BY OrderDate, Id确保当多条记录OrderDate相同时,按Id排序,避免前后行结果不确定。
  2. CTE Item2Records:集中处理筛选、前后行ID计算和目标行标记,逻辑清晰。
  3. 跨订单检查:用EXISTS子句高效判断是否存在其他订单的ItemId=2记录,性能优于COUNT(*)。
  4. 边界情况兼容:如果目标行是排序后的第一行/最后一行,LAG()/LEAD()会返回NULL,此时对应结果集不会有该行数据(因为JOIN匹配不到),符合预期。

运行结果

执行后你会得到:

  • 目标行的上一行记录(Id=4,OrderDate=2018-06-04)
  • 目标行的下一行记录(Id=5,OrderDate=2018-06-14)
  • 跨订单检查结果:ItemId=2存在于其他订单中

内容的提问来源于stack exchange,提问作者Lajith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:08:45