Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.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
选择PostgreSQL表中每个组的最后一行_Sql_Postgresql - Fatal编程技术网

选择PostgreSQL表中每个组的最后一行

选择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对

我有一张表,如下所示:

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删除所有其他记录
您需要任何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')
             );