所以我有此产品信息表。每次更改特定产品时,都会在新行中插入新值,包括时间戳和修改它的用户。
为了显示信息,我在搜索特定产品的最新行(该行由product_id列标识)。
但是现在我需要知道谁是最后一个修改名为状态的特定列的人。
因此,假设我的表格包含此内容
因此,本质上我需要编写一个查询,该查询将告诉我该给定列的最后更改时间。
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;
最里面的子查询将每个值与其先前的值进行比较。中间子查询枚举状态变化的产品的每一行。外部查询过滤器以获取最新的查询。
如果您的数据库不支持窗口函数,则逻辑要复杂一些。
首先,请考虑以下查询,该查询为您提供每idkey
具有最新status
的行的前product_id
:
select product_id, 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 | min(keyid)---------:| ---------:598 | 13456 | 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 |名称|状态|用户|密码---------:| :- -----:| :- ----:598 | prdd | 2 |凯特13456 | prrr | 3 |约翰| 15