Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 每组每个项目的最后记录_Sql_Sql Server_Greatest N Per Group - Fatal编程技术网

Sql 每组每个项目的最后记录

Sql 每组每个项目的最后记录,sql,sql-server,greatest-n-per-group,Sql,Sql Server,Greatest N Per Group,简化问题: 在表1中,我们有列:RowID、ItemID、BranchID、RoomID、Date、Qty 我正在尝试检索每个BranchID中每个RoomID中ItemID的最后数量 一旦我开始这样做,计划是将table1连接到ItemIDTable、BranchIDTable、RoomIDTable,以获取ID的名称 通过使用MAXDate,我得到了仅在一个RoomID中的ItemID的数量,但是如果ItemID在多个RoomID中,函数MAXDate将返回所有房间中的最新记录,而我需要每个

简化问题: 在表1中,我们有列:RowID、ItemID、BranchID、RoomID、Date、Qty

我正在尝试检索每个BranchID中每个RoomID中ItemID的最后数量

一旦我开始这样做,计划是将table1连接到ItemIDTable、BranchIDTable、RoomIDTable,以获取ID的名称

通过使用MAXDate,我得到了仅在一个RoomID中的ItemID的数量,但是如果ItemID在多个RoomID中,函数MAXDate将返回所有房间中的最新记录,而我需要每个房间的最新记录

ItemID=50和BranchID=4的数据集:

+--------+----------+--------+-----+---------------------+------------+------------+--------------+ | ItemID | BranchID | RoomID | Qty | Date | ItemIDName | RoomIDNAme | BranchIDName | +--------+----------+--------+-----+---------------------+------------+------------+--------------+ | 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 | +--------+----------+--------+-----+---------------------+------------+------------+--------------+ 结果我从两个室友中选择了最新的一个:

+--------+----------+--------+-----+---------------------+------------+------------+--------------+ | ItemID | BranchID | RoomID | Qty | Date | ItemIDName | RoomIDNAme | BranchIDName | +--------+----------+--------+-----+---------------------+------------+------------+--------------+ | 50 | 4 | 2 | 8 | 2019-12-12 13:30:25 | ItemA | RoomA | BranchB | +--------+----------+--------+-----+---------------------+------------+------------+--------------+ 每个室友的预期最新数量:

+--------+----------+--------+-----+---------------------+------------+------------+--------------+ | ItemID | BranchID | RoomID | Qty | Date | ItemIDName | RoomIDNAme | BranchIDName | +--------+----------+--------+-----+---------------------+------------+------------+--------------+ | 50 | 4 | 1 | 7 | 2019-12-12 13:30:15 | ItemA | RoomB | BranchB | | 50 | 4 | 2 | 8 | 2019-12-12 13:30:25 | ItemA | RoomA | BranchB | +--------+----------+--------+-----+---------------------+------------+------------+--------------+ 查询本身:

SELECT 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) ) ) ORDER BY table1.ItemID 我试图缩短和简化标题,使其更具可读性。如果您能深入了解这一点,无论是让这个查询工作起来,还是使用更好的方法,A都将不胜感激

您可以使用行数窗口功能:

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的一个条件:

此外,应该重写该条件以使用等式而不是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

这两个答案都很有帮助,效果也很好。我不确定一种方法是否优于另一种方法,我使用的记录不到10000条;我需要练习一下它的用法,现在有点难以理解。我相信窗口函数比相关子查询的性能更好。当您的数据增长时,您可以进一步查看“行数”选项。
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