postgresql 中第一个和最后一个值聚合函数可以正确处理 NULL 值

2024-04-07

我知道有聚合函数可以获取行的最后一个和第一个值PostgreSQL https://wiki.postgresql.org/wiki/First/last_%28aggregate%29

我的问题是,它们不能按我的需要工作。我可以使用 postgresql 向导的帮助。我正在使用 postgresql 9.2 - 以防该版本使提供解决方案更容易。

Query

select v.id, v.active, v.reg_no, p.install_date, p.remove_date 
from vehicle v 
    left join period p on (v.id = p.car_id) 
where v.id = 1 
order by v.id, p.install_date asc

返回 6 行:

id, active, reg_no, install_date, remove_date
1, TRUE, something, 2008-08-02 11:13:39, 2009-02-09 10:32:32
....
1, TRUE, something, 2010-08-15 21:16:40, 2012-08-25 07:44:30
1, TRUE, something, 2012-09-10 17:05:12, NULL

但是当我使用聚合查询时:

select max(id) as id, last(active) as active, first(install_date) as install_date, last(remove_date) as remove_date 
from (
    select v.id, v.active, v.reg_no, p.install_date, p.remove_date 
    from vehicle v 
      left join period p on (v.id = p.car_id) 
    where v.id = 1 
    order by v.id, p.install_date asc
) as bar 
group by id

然后我得到

id, active, install_date, remove_date
1, TRUE, 2008-08-02 11:13:39, 2012-08-25 07:44:30

not

id, active, install_date, remove_date
1, TRUE, 2008-08-02 11:13:39, NULL

正如我所料

如果最后一行的值为空,而不是最后一个现有值,是否可以以某种方式更改聚合函数以产生 NULL?

EDIT1

罗曼·佩卡 https://stackoverflow.com/users/1744834/roman-pekar提供替代解决方案 https://stackoverflow.com/questions/20345859/first-and-last-value-aggregate-functions-in-postgresql-that-work-correctly-with/20346066#20346066解决我的问题,但这不符合我的需求。原因是 - 我简化了原始查询。但我运行的查询更复杂。我意识到我的问题可能有其他解决方案 - 这就是为什么要更新帖子以包含原始的、更复杂的查询。这是:

select partner_id, sum(active) as active, sum(installed) as installed, sum(removed) as removed 
from (
    select 
    pc.partner_id as partner_id, 
    v.id, 
    CASE WHEN v.active = TRUE THEN 1 ELSE 0 END as active, 
    CASE WHEN first(p.install_date) BETWEEN '2013-12-01' AND '2014-01-01' THEN 1 ELSE 0 END as installed,
    CASE WHEN last(p.remove_date) BETWEEN '2013-12-01' AND '2014-01-01' THEN 1 ELSE 0 END as removed 
    from vehicle v 
        left join period p on (v.id = p.car_id) 
        left join partner_clients pc on (pc.account_id = v.client_id) 
    group by pc.partner_id, v.id, v.active
) as foo group by partner_id

正如您所看到的,我实际上需要获取几辆车的第一个和最后一个值,而不是一辆,最后汇总这些车辆的车主的这些车辆的数量。

/EDIT1


您可以使用窗口函数lead() and lag() http://www.postgresql.org/docs/9.1/static/functions-window.html检查第一条和最后一条记录,例如:

select
    max(a.id) as id,
    max(a.first) as first,
    max(a.last) as last
from (
    select
         v.id,
         case when lag(v.id) over(order by v.id, p.install_date) is null then p.install_date end as first,
         case when lead(v.id) over(order by v.id, p.install_date) is null then p.remove_date end as last
    from vehicle v 
       left join period p on (v.id = p.car_id) 
    where v.id = 1 
) as a

sql fiddle demo http://sqlfiddle.com/#!12/4ddf5/4

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

postgresql 中第一个和最后一个值聚合函数可以正确处理 NULL 值 的相关文章

  • 通过一个表中的列更新另一表中的列

    我有两张桌子 A 和 B 两者都有一个共同的列 name 并通过列 id 相互链接 表A中的 name 列是空的 而表B中有数据 我的任务是用相应的id填充从表B到表A的该列中的所有数据 我正在使用以下查询 UPDATE A SET A n
  • 使用 href 和 php 从 sql 数据库对 html 表进行排序

    我有一个 html 表 其中包含来自 php 吐出的 sql 表的产品数据 我想通过单击表列的标题对数据进行排序 我像这样输出我的表 php product list sql mysql query SELECT FROM products
  • 创建用于插入、修改和删除的数据库触发器的正确​​语法是什么

    我有一个看起来像是 SQL Server 中数据库触发器的基本场景 但我遇到了一个问题 我有桌子Users 身份证 姓名 电话等 我有桌子用户历史记录 id user id 操作 字段 时间戳 我想要一个数据库触发器 可以随时插入 更新或删
  • java.sql.SQLException: ORA-01005: 给定的密码为空;登录被拒绝

    我在尝试连接到数据库时遇到以下异常 java sql SQLException ORA 01005 null password given logon denied at oracle jdbc driver T4CTTIoer proce
  • oracle中是否有相当于concat_ws的东西?

    我有大量的列试图聚合在一起 其中大多数都有 NULL 值 我想分隔确实以 出现的值但我在oracle中找不到有效的方法来做到这一点 CONCAT WS 正是我所需要的 因为它不会在 NULL 值之间添加分隔符 但 Oracle 不支持这一点
  • 单个 sql 查询可以处理 sql server 中的 null 或值日期范围

    使用 SQL Server 2008 我有一个存储过程 其中开始日期和结束日期作为日期范围的输入参数 寻找一个singlesql 查询 其中在 where 子句中有一个开始日期和结束日期 可以处理日期均为空或都有值的两种情况 我不想使用 I
  • android sqlite 如果不存在则创建表

    创建新表时遇到一点问题 当我使用 CREATE TABLE 命令时 我的新表按应有的方式形成 但是当我退出活动时 应用程序崩溃 并且我在 logcat 中得到一个表已存在 如果我使用 CREATE TABLE IF NOT EXISTS 则
  • 更改 IdentityServer4 实体框架表名称

    我正在尝试更改由 IdentityServer4 的 PersistedGrantDb 和 ConfigurationDb 创建的默认表名称 并让实体框架生成正确的 SQL 例如 而不是使用实体IdentityServer4 EntityF
  • 选择表中的人员并排除妻子,但合并他们的名字

    我有一张桌子Person PersonID FirstName LastName 1 John Doe 2 Jane Doe 3 NoSpouse Morales 4 Jonathan Brand 5 Shiela Wife And a R
  • 从 oracle 中为每个组选择最新行

    我在留言簿中有一张包含用户评论的表格 列有 id user id 标题 评论 时间戳 我需要为每个用户选择最新行 我尝试使用 group by 执行此操作 但没有管理它 因为我无法在按 user id 分组的同一查询中选择任何其他内容 SE
  • SQL:列出多个连接语句中的重复记录?

    你好 以下查询在连接多个表后返回所有员工 select e from dbo EMP e join dbo HREMP a on a ID e ID join dbo LOGO c on c EMPID e id join dbo LOGO
  • 导出 Azure SQL 数据库时出现错误 SQL71501

    导出 Azure SQL 数据库时出现奇怪的错误 导出一直工作正常 直到最近发生一些架构更改 但现在出现错误 SQL71501 该数据库是V12 兼容性级别130 尽管master数据库仍兼容级别 120 该问题似乎是由一个新的表值函数引起
  • SQL:使用相等的键和最近的键进行连接(类似于 Pandas 的合并)

    例如 我有2个这样的表 对于表 1 中的每一行 我想获取该行 same customer id and nearest date 就我而言 table2 date lt table1 date 结果应该是这样的 我怎样才能在 SQL 中做到
  • SQL 删除自动命名约束

    我使用脚本在表上创建了一些约束 但未指定约束名称 结果 我最终受到了像这样的限制FK DOC OBGS kntr 54E63309例如 是否可以在不指定确切的约束名称的情况下删除该约束 例如 类似这样的东西 不起作用 ALTER TABLE
  • 在触发器中记录更新操作

    我有一个 UPDATE 触发器 它生成 INSERTED 和 DELETED 表 如下所示 INSERTED Id Name Surname 1 Stack Overflow 2 Luigi Saggese DELETED Id Name
  • 想要从字符格式转换为带小数的数字格式

    想要将字符格式 00001000000 转换为10000 00 请帮我 我已经尝试过 select to number 00012300 9999999999 99 nls numeric characters from dual 这个脚本
  • 获取MySql中重复行的列表

    我有一张这样的桌子 ID nachname vorname 1 john doe 2 john doe 3 jim doe 4 Michael Knight 我需要一个查询 该查询将从具有相同 nachname 和 vorname 的记录
  • OVER ORDER BY 中的多个列

    有没有办法在 OVER ORDER BY 子句中指定多个列 SELECT ROW NUMBER OVER ORDER BY A Col1 AS ID FROM MyTable A 上面的方法工作正常 但尝试添加第二列不起作用 SELECT
  • 如何在一列中存储数组或多个值

    运行 Postgres 7 4 是的 我们正在升级 我需要将 1 到 100 个选定项目存储到数据库的一个字段中 98 的情况下 只会输入 1 个项目 而 2 的情况下 如果是这样的话 会输入多个项目 这些项目只不过是文本描述 截至目前 长
  • oracle日期序列?

    我有一个 oracle 数据库 我需要一个包含 2 年所有日期的表 例如来自01 01 2011 to 01 01 2013 首先我想到了一个序列 但显然唯一支持的类型是数字 所以现在我正在寻找一种有效的方法来做到这一点 欢呼骗局 如果您想

随机推荐