我正在尝试获取有关获取选定行的上一行和下一行的语句。
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'), --this
(3, 2, 1, '2018-06-04', 'DR'),
(4, 2, 2, '2018-06-04', 'D'), --this
(5, 3, 2, '2018-06-14', 'DD'), --this
(6, 4, 2, '2018-06-14', 'R');
DECLARE
@ItemId int = 2,
@orderid int = 10
必填输出:
该过程的输入是订单ID = 10且项目ID = 2,我需要检查item-2是否处于其他任何顺序,即根据订单日期仅匹配记录/订单的上一项和下一项
答案 0 :(得分:1)
这是你的后代吗?
Declare @OderDetail table
(Id int primary key,OrderId int,ItemId INT,Lookup varchar(15))
Insert @OderDetail values (1,1, 1,'A')
Insert @OderDetail values (2,1, 2,'BE')
Insert @OderDetail values (3,2, 1,'DR')
Insert @OderDetail values (4,2,2, 'D')
Insert @OderDetail values (5,3,2, 'DD')
Insert @OderDetail values (6,4,2, 'R');
declare @ItemId int=2 , @orderid int = 2;
查询
With cte As
(
Select ROW_NUMBER() OVER(ORDER BY OrderDate) AS RecN,
*
From @OderDetail Where ItemId=@ItemId
)
Select * From cte Where
RecN Between ((Select Top 1 RecN From cte Where OrderId = @orderid) -1) And
((Select Top 1 RecN From cte Where OrderId = @orderid) +1)
Order by id
结果:
RecN Id OrderId ItemId Lookup
1 2 1 2 BE
2 4 2 2 D
3 5 3 2 DD
答案 1 :(得分:1)
根据给定的数据集进行更新:我看到了您要进行的操作。请注意,在某些情况下,给定的行之前没有行-因此它仅返回2而不是3。在这里,我更新了CTE版本。取消注释其他行以查看3而不是2,因为在具有该Itemid的所选行之前有一个。
添加了一个变量来演示如何更好地允许您在更改该数字(即传递参数)之前和之后获得1或在之前/之后获得2-如果行数更少,或者在获得之前或之后没有行在该限制范围内尽可能多。
所有版本的数据设置:
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'), --this
(3, 2, 1, '2018-06-04', 'DR'),
(4, 2, 2, '2018-06-04', 'D'), --this
(5, 3, 2, '2018-06-14', 'DD'), --this
(9, 4, 2, '2018-06-14', 'DD'),
(6, 4, 2, '2018-06-14', 'R'),
--(10, 10, 2, '2018-06-02', 'BE'), -- un-comment to see one before
(23, 4, 2, '2018-06-14', 'R');
DECLARE
@ItemId int = 2,
@orderid int = 2;
CTE更新版本:
DECLARE @rowsBeforeAndAfter INT = 1;
;WITH cte AS (
SELECT
Id,
OrderId,
ItemId,
OrderDate,
[Lookup],
ROW_NUMBER() OVER (ORDER BY OrderDate,Id) AS RowNumber
FROM @OderDetail
WHERE
ItemId = @itemId -- all matches of this
),
myrow AS (
SELECT TOP 1
Id,
OrderId,
ItemId,
OrderDate,
[Lookup],
RowNumber
FROM cte
WHERE
ItemId = @itemId
AND OrderId = @orderid
)
SELECT
cte.Id,
cte.OrderId,
cte.ItemId,
cte.OrderDate,
cte.[Lookup],
cte.RowNumber
FROM ctE
INNER JOIN myrow
ON ABS(cte.RowNumber - myrow.RowNumber) <= @rowsBeforeAndAfter
ORDER BY OrderDate, OrderId;
您可能希望使用CTE方法(请参阅本文的结尾)
只需指出,这将获得正确的结果,但可能并非您所追求的,因为它取决于行顺序,并且项id并非具有这两个值的实际行:
SELECT TOP 3
a.Id,
a.OrderId,
a.ItemId,
a.Lookup
FROM @OderDetail AS a
WHERE
a.ItemId = @ItemId
要解决此问题,您可以将ORDER BY
和TOP 1
与UNION
一起使用,有点难看。 (已使用日期排序和ID上的!=更新。)
SELECT
u.Id,
u.OrderId,
u.OrderDate,
u.ItemId,
u.Lookup
FROM (
SELECT
a.Id,
a.OrderId,
a.OrderDate,
a.ItemId,
a.Lookup
FROM @OderDetail AS a
WHERE
a.ItemId = @ItemId
AND a.OrderId = @orderid
UNION
SELECT top 1
b.Id,
b.OrderId,
b.OrderDate,
b.ItemId,
b.Lookup
FROM @OderDetail AS b
WHERE
b.ItemId = @ItemId
AND b.OrderId != @orderid
ORDER BY b.OrderDate desc, b.OrderId
UNION
SELECT top 1
b.Id,
b.OrderId,
b.OrderDate,
b.ItemId,
b.Lookup
FROM @OderDetail AS b
WHERE
b.ItemId = @ItemId
AND b.OrderId != @orderid
ORDER BY b.OrderDate asc, b.OrderId
) AS u
ORDER BY u.OrderDate asc, u.OrderId
答案 2 :(得分:1)
另一种可能的方法是使用$('input[type=file]').on('change', function(e){....
和LAG()
函数,它们从前一行和后一行返回的数据形成相同的结果集。
LEAD()
输出:
-- Table
DECLARE @OrderDetail TABLE (
Id int primary key,
OrderId int,
ItemId int,
OrderDate DateTime2,
Lookup varchar(15)
)
INSERT INTO @OrderDetail
VALUES
(1, 10, 1, '2018-06-11', 'A'),
(2, 10, 2, '2018-06-11', 'BE'), --this
(3, 2, 1, '2018-06-04', 'DR'),
(4, 2, 2, '2018-06-04', 'D'), --this
(5, 3, 2, '2018-06-14', 'DD'), --this
(6, 4, 2, '2018-06-14', 'R');
-- Item and order
DECLARE
@ItemId int = 2,
@orderid int = 10
-- Statement
-- Get previois and next ID for every order, grouped by ItemId, ordered by OrderDate
;WITH cte AS (
SELECT
Id,
LAG(Id, 1) OVER (PARTITION BY ItemId ORDER BY OrderDate) previousId,
LEAD(Id, 1) OVER (PARTITION BY ItemId ORDER BY OrderDate) nextId,
ItemId,
OrderId,
Lookup
FROM @OrderDetail
)
-- Select current, previous and next order
SELECT od.*
FROM cte
CROSS APPLY (SELECT * FROM @OrderDetail WHERE Id = cte.Id) od
WHERE (cte.OrderId = @orderId) AND (cte.ItemId = @ItemId)
UNION ALL
SELECT od.*
FROM cte
CROSS APPLY (SELECT * FROM @OrderDetail WHERE Id = cte.previousId) od
WHERE (cte.OrderId = @orderId) AND (cte.ItemId = @ItemId)
UNION ALL
SELECT od.*
FROM cte
CROSS APPLY (SELECT * FROM @OrderDetail WHERE Id = cte.nextId) od
WHERE (cte.OrderId = @orderId) AND (cte.ItemId = @ItemId)
答案 3 :(得分:0)
我认为它很简单,您可以使用左侧外部连接或外部应用来检查min(Id)和Max(id)
喜欢
Declare @ItemID int = 2
Select * From @OderDetail A
Outer Apply (
Select MIN(A2.Id) minID, MAX(A2.Id) maxID From @OderDetail A2
Where A2.ItemId =@ItemID
) I05
Outer Apply(
Select * From @OderDetail Where Id=minID-1
Union All
Select * From @OderDetail Where Id=maxID+1
) I052
Where A.ItemId =@ItemID Order By A.Id
让我知道这对您有帮助还是您遇到任何问题...
此致