PostgreSQL能否返回一个值列表,其中后一个值会覆盖前一个值?

PostgreSQL能否返回一个值列表,其中后一个值会覆盖前一个值?,sql,postgresql,select,greatest-n-per-group,Sql,Postgresql,Select,Greatest N Per Group,下表表示给定文件的许可证上的决策事件 我想以该文件的许可证列表结束。如果事件的Removed列为False,则会添加一个许可证,但每个文件的每个许可证不得超过一个。如果事件的Removed列为True,则将推翻特定许可证的所有先前添加事件。晚一点发生的事件优先于之前发生的事件 对于下面的事件,我想返回[a,B]的列表。许可证A有添加、删除和添加事件,因此会返回。许可证B有添加、添加的事件,因此会返回,但不会重复。许可证C包含事件add、add、remove,因此它不会被删除,因为后者的删除会使两

下表表示给定文件的许可证上的决策事件

我想以该文件的许可证列表结束。如果事件的Removed列为False,则会添加一个许可证,但每个文件的每个许可证不得超过一个。如果事件的Removed列为True,则将推翻特定许可证的所有先前添加事件。晚一点发生的事件优先于之前发生的事件

对于下面的事件,我想返回[a,B]的列表。许可证A有添加、删除和添加事件,因此会返回。许可证B有添加、添加的事件,因此会返回,但不会重复。许可证C包含事件add、add、remove,因此它不会被删除,因为后者的删除会使两个add事件无效

这是否可以通过PostgreSQL查询实现,还是需要在以后处理数据

+------+---------+---------+
| Time | License | Removed |
+------+---------+---------+
|    1 | A       | False   |
|    2 | A       | True    |
|    3 | A       | False   |
|    4 | B       | False   |
|    5 | B       | False   |
|    6 | C       | False   |
|    7 | C       | False   |
|    8 | C       | True    |
+------+---------+---------+

您可以在子查询中使用
distinct on
对每个许可证的最后一条记录进行筛选,然后筛选出已删除的记录:

select license
from (select distinct on (license) t.* from mytable t order by license, time desc) t
where not removed

如果我理解正确,您希望每个许可证的最后一个事件。如果您知道窗口函数是如何工作的,这很简单:您可以使用窗口对表进行分区,然后在每个窗口内通过排序等方式进行操作。在这种情况下,您希望在许可证上进行分区,然后按时间排序(降序),最后选择每个窗口的最新条目:

SELECT "License", "Removed" FROM (
    SELECT *, rank() OVER (PARTITION BY "License" ORDER BY "Time" DESC)) X
 WHERE rank = 1

如果您想更好地了解它的工作原理,请尝试自行执行内部的
SELECT

您可以使用聚合:

select license
from t
group by license
having max(time) = max(time) filter (where not removed);
having
子句检查许可证的最长时间是否未“删除”

这三个答案都很合理。一般来说,对于获取一行,Postgres中的
distinct on
优于
row\u number()
。如果您对子查询有严格的厌恶,我将提供此选项