选择PostgreSQL表中每个组的最后一行
我有一张表,如下所示: TS 序列号 活动 住址 1. 123456 AAABBCCC 2. 123456 AAABBCCC 3. 123456 A. AAABBCCC 4. 123456 E AAABBCCC 5. 876543 A. 统一 6. 123456 A. AAABBCCC 7. 123456 E 哇哇 8. 123456 哇哇 9 876543 E 苜蓿 10 876543 苜蓿 使用 只选择最后一个A在最后一个E之前的那些SERU no分区 删除所有非电子记录 按时间戳DESC对剩余的E记录进行排序,以获得每组中最新的最上面的记录,并使用DISTINCT ON claus删除所有其他记录选择PostgreSQL表中每个组的最后一行,sql,postgresql,Sql,Postgresql,我有一张表,如下所示: TS 序列号 活动 住址 1. 123456 AAABBCCC 2. 123456 AAABBCCC 3. 123456 A. AAABBCCC 4. 123456 E AAABBCCC 5. 876543 A. 统一 6. 123456 A. AAABBCCC 7. 123456 E 哇哇 8. 123456 哇哇 9 876543 E 苜蓿 10 876543 苜蓿 使用 只选择最后一个A在最后一个E之前的那些SERU no分区 删除所有非电子记录 按时间戳DESC对
您需要任何E行后面不跟任何A或E且序列号相同 这在SQL中翻译为:
SELECT Serial_Number, Address
FROM Tbl ret
WHERE Activity = 'E'
AND NOT EXISTS (
SELECT *
FROM Tbl witness
WHERE witness.Serial_Number = ret.Serial_Number
AND witness.TS > ret.TS
AND witness.Activity IN ('A', 'E')
);
嗯。如果要包括无效记录,可以使用distinct on:
select ser_no, ts,
(case when activity = 'E' then address
else 'INVALID'
end)
from t
where activity in ('E', 'A')
order by (ser_no, ts desc);
这仅获取每个序列号的最后一行E/A,并相应地分配地址
如果要删除它们,则仍然可以在不使用子查询的情况下进行管理。如果Postgres有一个first/last聚合函数就好了,但您可以用数组来模拟它:
select ser_no, max(ts),
(array_agg(address order by ts desc))[1] as last_address
from t
where activity in ('E', 'A')
group by ser_no
having max(ts) filter (where activity = 'E') > max(ts) filter (where activity = 'A');
对于子查询,我建议:
select t.*
from t
where t.activity = 'E' and
t.ts = (select max(t2.ts)
from t t2
where t2.ser_no = t.ser_no and
t2.activity in ('A', 'E')
);
当最后一行是E或A的最后一行时,这将获取最后一行E。在问题中添加所需输出是一种很好的做法。@HenrikWiese答案有帮助吗?如果没有,应该改变什么。如果他们在任何方面有所帮助:请不要忘记向上投票,这是为了表彰回答者在您的问题上投入了一些内部观点的时间,如果有人完全解决了所描述的问题,请另外接受此答案以结束问题。谢谢。
select t.*
from t
where t.activity = 'E' and
t.ts = (select max(t2.ts)
from t t2
where t2.ser_no = t.ser_no and
t2.activity in ('A', 'E')
);