SQL:查询以获取特定列值的最后更改
我有这张产品信息表。每次更改特定产品时,都会插入一个新行,其中包含新值,包括时间戳和修改它的用户 为了显示信息,我搜索特定产品的最新行,该行由一列product_id标识 但是现在我需要知道谁是最后一个修改了一个特定列的人,这个列名为status 假设我的桌子由这个组成 所以本质上,我需要编写一个查询,告诉我给定列的最后一次更改是什么时候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 | 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问题,因为没有答案,我只是修改了表,使其有更多的列来存储我需要的数据。但这会更加优雅,也更容易实现