Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.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_Select_Greatest N Per Group_Gaps And Islands - Fatal编程技术网

SQL:查询以获取特定列值的最后更改

SQL:查询以获取特定列值的最后更改,sql,select,greatest-n-per-group,gaps-and-islands,Sql,Select,Greatest N Per Group,Gaps And Islands,我有这张产品信息表。每次更改特定产品时,都会插入一个新行,其中包含新值,包括时间戳和修改它的用户 为了显示信息,我搜索特定产品的最新行,该行由一列product_id标识 但是现在我需要知道谁是最后一个修改了一个特定列的人,这个列名为status 假设我的桌子由这个组成 所以本质上,我需要编写一个查询,告诉我给定列的最后一次更改是什么时候 product_id | name | status | user | keyid -----------------------------------

我有这张产品信息表。每次更改特定产品时,都会插入一个新行,其中包含新值,包括时间戳和修改它的用户

为了显示信息,我搜索特定产品的最新行,该行由一列product_id标识

但是现在我需要知道谁是最后一个修改了一个特定列的人,这个列名为status

假设我的桌子由这个组成

所以本质上,我需要编写一个查询,告诉我给定列的最后一次更改是什么时候

product_id | name | status   | user | keyid
--------------------------------------------
598        | prrr | 0        | john | 10
598        | prod | 1        | jane | 11
456        | abcd | 2        | mac  | 12
598        | prdd | 2        | kate | 13
598        | rdpd | 2        | jane | 14
456        | prrr | 3        | john | 15
456        | abbb | 3        | kate | 16
因此,598产品的最新信息如下:

598 rdpd 2 jane 14
但最后一个被释放的人是凯特

产品456的最新信息如下:

456 abbb 3 kate 16
但最后一个被释放的人是约翰

因此,理想情况下,我希望编写一个返回

598 kate 13
456 john 15

我甚至还不知道如何编写这样的查询,所以我想知道是否有人可以在这里帮助我。

您可以使用窗口函数:

select t.*
from (select t.*, row_number() over (partition by productid order by keyid desc) as seqnum
      from (select t.*,
                   lag(status) over (partition by productid order by keyid) as prev_status
            from t
           ) t
      where prev_status is null or prev_status <> status
     ) t
where seqnum = 1;

最里面的子查询将每个值与其以前的值进行比较。中间子查询枚举状态发生更改的产品的每一行。外部查询筛选以获取最新的查询。

您可以使用窗口功能:

select t.*
from (select t.*, row_number() over (partition by productid order by keyid desc) as seqnum
      from (select t.*,
                   lag(status) over (partition by productid order by keyid) as prev_status
            from t
           ) t
      where prev_status is null or prev_status <> status
     ) t
where seqnum = 1;

最里面的子查询将每个值与其以前的值进行比较。中间子查询枚举状态发生更改的产品的每一行。外部查询筛选以获取最新的查询。

如果您的数据库不支持窗口功能,则逻辑会稍微复杂一些

作为启动程序,考虑下面的查询,它为您提供每个产品的最新状态的行的第一个IDKE:< /P> 这将返回:

product_id | min(keyid) ---------: | ---------: 598 | 13 456 | 15 然后可以使用此结果集筛选表:

select t.*
from mytable t
where t.keyid in (
    select min(keyid)
    from mytable t
    where not exists (
        select 1 
        from mytable t1 
        where t1.product_id = t.product_id and t1.status <> t.status and t1.keyid > t.keyid
    )
    group by product_id
)
结果:

product_id | name | status | user | keyid ---------: | :--- | -----: | :--- | ----: 598 | prdd | 2 | kate | 13 456 | prrr | 3 | john | 15
如果您的数据库不支持窗口函数,那么逻辑就要复杂一些

作为启动程序,考虑下面的查询,它为您提供每个产品的最新状态的行的第一个IDKE:< /P> 这将返回:

product_id | min(keyid) ---------: | ---------: 598 | 13 456 | 15 然后可以使用此结果集筛选表:

select t.*
from mytable t
where t.keyid in (
    select min(keyid)
    from mytable t
    where not exists (
        select 1 
        from mytable t1 
        where t1.product_id = t.product_id and t1.status <> t.status and t1.keyid > t.keyid
    )
    group by product_id
)
结果:

product_id | name | status | user | keyid ---------: | :--- | -----: | :--- | ----: 598 | prdd | 2 | kate | 13 456 | prrr | 3 | john | 15
我以前有过一个问题,在哪里建议了窗口函数。然而,我的服务器数据库不支持窗口功能。我以前有个问题,建议在哪里使用窗口功能。但是我的服务器数据库不支持窗口功能。非常感谢您的回答!我一定会试试的。然而,我必须快速解决de问题,因为没有答案,我只是修改了表,使其有更多的列来存储我需要的数据。但这会更优雅,更容易实现。非常感谢你的回答!我一定会试试的。然而,我必须快速解决de问题,因为没有答案,我只是修改了表,使其有更多的列来存储我需要的数据。但这会更加优雅,也更容易实现