Sql Postgres-使用匹配的校验和从每个组返回具有最新时间戳的行
我有一个表Postgres 9.3,定义如下Sql Postgres-使用匹配的校验和从每个组返回具有最新时间戳的行,sql,postgresql,greatest-n-per-group,Sql,Postgresql,Greatest N Per Group,我有一个表Postgres 9.3,定义如下 CREATE TABLE tsrs ( id SERIAL PRIMARY KEY, customer_id INTEGER NOT NULL REFERENCES customers, timestamp TIMESTAMP WITHOUT TIME ZONE, licensekeys_checksum VARCHAR(32)); 此处的相关详细信息包括客户id、时间戳和licensekeys\u校验和。
CREATE TABLE tsrs (
id SERIAL PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES customers,
timestamp TIMESTAMP WITHOUT TIME ZONE,
licensekeys_checksum VARCHAR(32));
此处的相关详细信息包括客户id、时间戳和licensekeys\u校验和。此表中可能有多个条目具有相同的客户id,其中一些条目可能具有匹配的licensekey\u校验和条目,而一些条目可能不同
我感兴趣的是构造一个查询,该查询将返回一个表,其中每组行包含1行,并且具有匹配的licensekeys\u校验和项。为每个组返回的行应该是具有最新/最新时间戳的条目
如果这是显而易见的,我很抱歉——我对SQL很陌生,对这个查询有点不了解。如有任何帮助/建议,将不胜感激
样本输入
期望输出
编辑:
我根据下面的评论和数小时的互联网搜索,拼凑出了一个查询:
select * from tsrs
inner join (
select licensekeys_checksum, max(timestamp) as mts
from tsrs
group by licensekeys_checksum )
x on x.licensekeys_checksum = tsrs.licensekeys_checksum and x.mts = tsrs.timestamp;
这似乎有效,但很难证实,如果我说我完全理解它的工作原理,那我就是在撒谎。有人能告诉我我是否走对了道路吗?试试这个
select *
from tsrs
where (timestamp,licensekeys_checksum) in (
select max(timestamp)
,licensekeys_checksum
from tsrs
group by licensekeys_checksum)
或
参考:,和试试这个
select *
from tsrs
where (timestamp,licensekeys_checksum) in (
select max(timestamp)
,licensekeys_checksum
from tsrs
group by licensekeys_checksum)
或
参考:,和替代重复数据消除,使用不存在
替代重复数据消除,使用不存在
问题中的查询应比当前接受答案中的查询执行得更好。用解释分析进行测试 如果您正在寻找更简单、更快的解决方案,请在以下位置使用DISTINCT: -建立在@Wingedparter kudos提供的基础上。 详细说明:
问题中的查询应比当前接受答案中的查询执行得更好。用解释分析进行测试 如果您正在寻找更简单、更快的解决方案,请在以下位置使用DISTINCT: -建立在@Wingedparter kudos提供的基础上。 详细说明:
使用GROUP BY和MAX。请添加一些样本数据和基于该格式化文本的预期输出,是否有校验和和和时间戳相等的记录?顺便说一句:时间戳是列的一个坏名称,因为它也是数据类型的名称。这可能会使解析器、框架或人员感到困惑。@wingedparter哎呀,这是不正确的。好样的!我已经解决了这个问题。谢谢:使用GROUP BY和MAX。请根据格式化文本添加一些示例数据和预期输出,是否有校验和和和时间戳相等的记录?顺便说一句:时间戳是列的一个坏名称,因为它也是数据类型的名称。这可能会使解析器、框架或人员感到困惑。@wingedparter哎呀,这是不正确的。好样的!我已经解决了这个问题。谢谢:这将返回与我上面的查询相同的结果,但至少对我来说更容易理解:。我将改用这个版本。非常感谢!这将返回与上面的查询相同的结果,但至少对我来说更容易理解:。我将改用这个版本。非常感谢!
select *
from tsrs
where (timestamp,licensekeys_checksum) in (
select max(timestamp)
,licensekeys_checksum
from tsrs
group by licensekeys_checksum)
with cte as (
select id
,customer_id
,timestamp
,licensekeys_checksum
,row_number () over (partition by licensekeys_checksum ORDER BY timestamp DESC) as rk
from tsrs)
select id
,customer_id
,timestamp
,licensekeys_checksum
from cte where rk=1 order by id
SELECT *
FROM tsrs t
WHERE NOT EXISTS (
SELECT *
FROM tsrs x
WHERE x.customer_id = t.customer_id -- same customer
AND x.licensekeys_checksum = t.licensekeys_checksum -- same checksum
AND x.ztimestamp > t.ztimestamp -- but more recent
);
SELECT DISTINCT ON (licensekeys_checksum) *
FROM tsrs
ORDER BY licensekeys_checksum, timestamp DESC;