我有下面的更新表.....

refer event_date column detail event_type cat1
2 yesterday abc type 3 cat x
2 last week abc3 type 11 cat b
2 today abc123 type 4 cat a
2 last month xyz type 22 cat z
2 last year wtf type 11 cat z

因此,对于REFER=2

abc123 is the latest update based on latest date.
abc3 is the latest update for event_type 11 and cat = b
xyz is the latest update for cat z

是否可以在单个查询中完成此操作?我可以获得结果的唯一方法是使用单独的查询或CTE:

with cte1 as (
select  t.refer,
        t.detail
from    
        (
            select ch.refer,
                  ch.detail,
                    row_number() over (partition by refer order by event_date desc) as rn
            from    table  ch
            ) as latest
    where ch.rn = 1
)
cte2 as(
select  t.refer,
        t.detail
from    
        (
            select ch.refer,
                  ch.detail,
                    row_number() over (partition by refer order by event_date desc) as rn
            from    table  ch
            where   event_type = '11'
            and     cat = 'b'
            ) as latest
    where ch.rn = 1
)
cte3 as(
select  t.refer,
        t.detail
from    
        (
            select ch.ref,
                  ch.detail,
                    row_number() over (partition by refer order by event_date desc) as rn
            from    table  ch
            where   event_type = 'z'   
            ) as latest
    where ch.rn = 1
    and cat = 'z'
);

推荐答案

我们可以用三个row_number枚举三个分区,然后使用条件聚合进行透视:

select refer,
    max(detail) filter(where rn1 = 1                                  ) detail,
    max(detail) filter(where rn2 = 1 and cat = 'z'                    ) detail2,
    max(detail) filter(where rn3 = 1 and cat = 'b' and event_type = 11) detail3
from (
    select t.*,
        row_number() over(partition by refer                  order by event_date desc) rn1,
        row_number() over(partition by refer, cat             order by event_date desc) rn2,
        row_number() over(partition by refer, event_type, cat order by event_date desc) rn3
    from mytable t
) t
group by refer
refer detail detail2 detail3
2 abc123 xyz abc3

fiddle

当然,这假设您以类似date的数据类型存储日期,而不是像'today''last year'这样的字符串.


或者,如果您希望结果按行而不是按列显示,那么我们不需要聚合:

select *
from (
    select t.*,
        row_number() over(partition by refer                  order by event_date desc) rn1,
        row_number() over(partition by refer, cat             order by event_date desc) rn2,
        row_number() over(partition by refer, event_type, cat order by event_date desc) rn3
    from mytable t
) t
where
    rn1 = 1
    or (rn2 = 1 and cat = 'z')
    or (rn3 = 1 and cat = 'b' and event_type = 11)

Sql相关问答推荐

SQL计数所有值在联接范围内的行

在SQL Server中使用LEFT连接包含特定记录

LAG函数通过丢弃空值返回前一行

在postgres中动态计算出现次数并插入到json中

从依赖于其他表的值的XREF表中的值分组获得正确的计数?

SQL:如何将相应位置的两个数组中的元素组合在一起

如何根据行状态设置正确的标志

HAVING子句内部过滤的正确方法

无法将发票与产品价格相关联

将FLOAT转换为VARBINARY,然后再转换回FLOAT

按连续相等值分组排序

PostgreSQL-按距离阈值挤压相邻行的性能

向表中添加新列取决于表的日期列(unpivot)

创建具有多个子查询的 SQL 视图

多行状态下的分组查询判断状态

使用对 nvarchar 列的多个 LIKE 操作优化 SQL 查询

Postgresql 需要一个查询,为我提供所有没有具有特定状态值的子元素的父母

添加一列并根据其他列值进行填充

SQL - 使用子查询返回多行的 LIKE 命令

BigQuery - 将 TIMESTAMP 转换为 HH:MM:SS,然后识别 TIME_DIFF