简化问题:在表“ table1”中,我们有列:RowID,ItemID,BranchID,RoomID,Date,Qty
我正在尝试在每个BranchID中的每个RoomID中检索ItemID的最后一个数量。
一旦完成,计划是将table1联接到ItemIDTable,BranchIDTable,RoomIDTable以获取ID的名称。
通过使用MAX(Date),我得到了仅位于一个RoomID中的ItemID的数量,但是,如果ItemID在多个RoomID中,则函数MAX(Date)返回所有房间中的最新记录,而我需要每个房间的最新信息。
ItemID = 50和BranchID = 4的数据集:
+ -------- + ---------- + -------- + ----- + -------------- ------- + ------------ + ------------ + -------------- +| ItemID | BranchID | RoomID |数量日期| ItemIDName | RoomIDNAme | BranchIDName |+ -------- + ---------- + -------- + ----- + -------------- ------- + ------------ + ------------ + -------------- +| 50 | 4 | 1 | 7 | 2019-12-12 13:30:15 | ItemA |房间B |分公司B || 50 | 4 | 2 | 5 | 2019-12-12 13:30:20 | ItemA |房间A |分公司B || 50 | 4 | 2 | 8 | 2019-12-12 13:30:25 | ItemA |房间A |分公司B |+ -------- + ---------- + -------- + ----- + -------------- ------- + ------------ + ------------ + -------------- +
我得到的结果(它从两个RoomID中选择了最新的一个:]
+ -------- + ---------- + -------- + ----- + -------------- ------- + ------------ + ------------ + -------------- +| ItemID | BranchID | RoomID |数量日期| ItemIDName | RoomIDNAme | BranchIDName |+ -------- + ---------- + -------- + ----- + -------------- ------- + ------------ + ------------ + -------------- +| 50 | 4 | 2 | 8 | 2019-12-12 13:30:25 | ItemA |房间A |分公司B |+ -------- + ---------- + -------- + ----- + -------------- ------- + ------------ + ------------ + -------------- +
预期(每个RoomID的最新数量):
+ -------- + ---------- + -------- + ----- + -------------- ------- + ------------ + ------------ + -------------- +| ItemID | BranchID | RoomID |数量日期| ItemIDName | RoomIDNAme | BranchIDName |+ -------- + ---------- + -------- + ----- + -------------- ------- + ------------ + ------------ + -------------- +| 50 | 4 | 1 | 7 | 2019-12-12 13:30:15 | ItemA |房间B |分公司B || 50 | 4 | 2 | 8 | 2019-12-12 13:30:25 | ItemA |房间A |分公司B |+ -------- + ---------- + -------- + ----- + -------------- ------- + ------------ + ------------ + -------------- +
查询本身:
选择table1.ItemID,table1.BranchID,table1.RoomID,table1。数量table1.Date,ItemIDTable.ItemIDName,RoomIDTable.RoomIDName,BranchIDTable.BranchIDName从表1内联接ItemIDTable ON table1.ItemID = ItemIDTable.ItemID内部联接RoomIDTable ON table1.RoomID = RoomIDTable.RoomID内联接Table1.BranchID = BranchIDTable.BranchID上的BranchIDTable哪里(表1.日期输入(SELECT MAX(日期)从表1其中(ItemID = table1.ItemID)和(BranchID = table1.BranchID)))订购table1.ItemID
我已尝试简化和简化标题以使其更具可读性。无论是使此查询正常工作还是使用更好的方法,A都会感谢您对此的任何见解。
您可以使用ROW_NUMBER()
窗口功能:
DECLARE @Tab TABLE (ItemID INT, BranchID INT, RoomID INT, Qty INT,Dt datetime,ItemIDName varchar(10),RoomIDNAme varchar(10),BranchIDName varchar(10))
insert @tab
values
(50,4,1,7,'2019-12-12 13:30:15','ItemA','RoomB','BranchB'),
(50,4,2,5,'2019-12-12 13:30:20','ItemA','RoomA','BranchB'),
(50,4,2,8,'2019-12-12 13:30:25','ItemA','RoomA','BranchB')
SELECT *
FROM(
SELECT row_number() over(partition by itemid, branchid, roomid order by dt desc) rn, *
FROM @Tab
) t
WHERE t.rn = 1
或与您的查询:
SELECT *
FROM(
SELECT ROW_NUMBER() OVER(PARTITION BY table1.ItemID, table1.BranchID, table1.RoomID, ORDER BY table1.Date DESC) rn
table1.ItemID,
table1.BranchID,
table1.RoomID,
table1.Qty,
table1.Date,
ItemIDTable.ItemIDName,
RoomIDTable.RoomIDName,
BranchIDTable.BranchIDName
FROM
table1 INNER JOIN
ItemIDTable ON table1.ItemID = ItemIDTable.ItemID INNER JOIN
RoomIDTable ON table1.RoomID = RoomIDTable.RoomID INNER JOIN
BranchIDTable ON table1.BranchID = BranchIDTable.BranchID
WHERE
(table1.Date IN
(
SELECT MAX(Date)
FROM table1
WHERE (ItemID = table1.ItemID) AND (BranchID = table1.BranchID)
)
)
) t
WHERE t.rn = 1
ORDER BY
table1.ItemID
我正在尝试在每个BranchID中的每个RoomID中检索ItemID的最后一个数量。
您使用关联子查询进行过滤的意图在我看来是个好主意。但是,您的WHERE
子句不能完全满足您的要求:它似乎缺少RoomID
上的条件:
WHERE
(table1.Date IN
(
SELECT MAX(Date)
FROM table1
WHERE (ItemID = table1.ItemID) AND (BranchID = table1.BranchID)
)
)
此外,由于子查询无论如何都会返回最大一条记录,因此该条件应重写为使用等式而不是IN
。请注意,此处大多数括号是多余的。最后,我建议使用表别名来消除子查询中的列名称的歧义。
考虑:
SELECT
t1.ItemID,
t1.BranchID,
t1.RoomID,
t1.Qty,
t1.Date,
i.ItemIDName,
r.RoomIDName,
b.BranchIDName
FROM
table1 t1
INNER JOIN ItemIDTable i ON t1.ItemID = i.ItemID
INNER JOIN RoomIDTable r ON t1.RoomID = r.RoomID
INNER JOIN BranchIDTable ON t1.BranchID = b.BranchID
WHERE t1.Date = (
SELECT MAX(t11.Date)
FROM table1 t11
WHERE
t11.ItemID = t1.ItemID
AND t11.BranchID = t1.BranchID
AND t11.RoomID = t1.RoomID
)
ORDER BY t1.ItemID