根据雪花中的字段值获取每个日期和数据透视表的最后一个值

Posted

技术标签:

【中文标题】根据雪花中的字段值获取每个日期和数据透视表的最后一个值【英文标题】:Get the last value of each date and pivot table based on field value in Snowflake 【发布时间】:2021-08-29 05:09:43 【问题描述】:

我正在尝试使用 Snowflake 根据时间戳“FIELD_TIME”获取“FIELD_NAME”中每个组的最后一个值。

我有下表,

我希望表格中的每个值都有一列(例如,产品数量、SKU 上线日期等),并且该列仅包含当天的最后一个值。如下表,

ISSUE_ID ISSUE_ID FIELD_TIME Number of Products Number of SKU live Date of SKU Live Number of SKU Not Created Work_In_Progress_Date Pending_Date Status Resolution
19229 X1 2021-08-01 55 21 2021-08-01 34 PENDING Null
19229 X1 2021-08-08 PENDING Null
19229 X1 2021-08-12 55 24 2021-08-01 31 2021-08-12 2021-08-12 PENDING Null

我尝试过last_value(FIELD_VALUE) over (partition by FIELD_NAME, ISSUE_ID order by field_time),但它给了我 23 行而不是 3 行的重复值。 我也试过lag(),但没有运气。

以下是我的代码,非常感谢任何帮助。

 select
           t.ISSUE_ID, t.issue_name,
    --        t.created_date,
           t.field_time::date as field_time,
           max(case when field_name = 'Number of Products' then field_value end) as Number_of_Products,
           max(case when field_name = 'Number of SKU live' then field_value end) as Number_of_SKU_Live,
           max(case when field_name = 'Number of SKU not created' then field_value end) as Number_of_SKU_Not_Created,
           max(case when field_name = 'Date of SKU live' then field_value end) as Date_of_SKU_Live,
           max(case when field_value = '10020' then date(t.field_time) end) as Work_In_Progress_Date,
           max(case when field_value = '10010' then date(t.field_time) end) as Pending_Date,
           t.status, t.resolution
           from
    (select fh.ISSUE_ID,
           i.issue_name,
           date(i.created_date) as created_date,
           fh.TIME as field_time,
           f.name as field_name,
           fh.value as field_value,
           i.status,
           i.resolution
    from JIRA.ISSUE_FIELD_HISTORY fh
             left join JIRA.FIELD f on fh.FIELD_ID = f.ID and f._FIVETRAN_DELETED = 0
             left join (select i0.created as created_date,r.name as resolution, i0.id, i0.key as issue_name, i0.status as status_id, s.name as status
                        from JIRA.issue i0
                                 left join JIRA.status s on i0.status = s.ID
                                 left join JIRA.RESOLUTION r on i0.RESOLUTION = r.ID
                 where i0._FIVETRAN_DELETED = 0
                 and i0.key like 'PIM%')
                 i on i.id = fh.ISSUE_ID
    where fh.ISSUE_ID in (select ID from ISSUE where PROJECT = 10041)
    and fh.FIELD_ID in ('customfield_10067', 'customfield_10063', 'customfield_10066', 'customfield_10068', 'status', 'resolution')
    -- and issue_name = 'PIM-11'
    qualify row_number() over (partition by issue_id, field_time::date, field_name order by field_time desc) = 1
    order by field_time) t
    group by issue_id, issue_name,created_date, field_time::date, status, resolution

使用的表格是,

ISSUE_FIELD_HISTORY:用于链接字段相关列的主表。 FIELD:用于获取与字段 ID 关联的字段名称的辅助表。 ISSUE:用于获取与每个问题相关的问题名称、ID 和状态 ID 的辅助表。 STATUS:获取与 ISSUE 表中的状态 ID 相关的状态名称。 RESOLUTION:获取分辨率状态(分辨率名称)。

【问题讨论】:

您的样本数据和期望的结果彼此无关。您的查询引用了一堆未定义的表和列。 我为每个使用的表添加了描述。 【参考方案1】:

我无法重现您的查询,因为您没有给出定义的表太多。但是,根据您的要求,下面是一个使用 PIVOT 的简化示例,它会给出预期的结果:

with cte as (
select 19229 as issue_id, 'X1' as issue_name, '2021-08-01 09:04:35'::timestamp_ntz as field_time, 'Status' as field_name, 10020 as field_value, 'Work In Progress' as status union all
select 19229 as issue_id, 'X1' as issue_name, '2021-08-01 09:04:35'::timestamp_ntz as field_time, 'Number of Products' as field_name, 55 as field_value, 'PENDING' as status union all
select 19229 as issue_id, 'X1' as issue_name, '2021-08-01 09:04:35'::timestamp_ntz as field_time, 'Number of SKU live' as field_name, 21 as field_value, 'PENDING' as status union all
select 19229 as issue_id, 'X1' as issue_name, '2021-08-08 06:19:05'::timestamp_ntz as field_time, 'Status' as field_name, 10010 as field_value, 'PENDING' as status
),
t as (
select ISSUE_ID,
           issue_name,
           field_time::date as field_date,
           field_name,
           field_value,
           last_value(status) over (partition by issue_id, field_time::date order by field_time desc) as last_status
    from cte
    qualify row_number() over (partition by issue_id, field_time::date, field_name order by field_time desc) = 1
)
select * from t
pivot(max(field_value) for field_name in ('Status', 'Number of Products', 'Number of SKU live')) as p
order by field_date
;

您必须在查询中使用 last_value(status),因为状态在一天中会发生变化,并且每个 field_value 可能会有所不同。这是查询的结果,每天给出一条记录,其中包含每个字段的最新值:

ISSUE_ID    ISSUE_NAME  FIELD_DATE  LAST_STATUS         'Status'    'Number of Products'    'Number of SKU live'
19229       X1          2021-08-01  Work In Progress    10020       55                      21
19229       X1          2021-08-08  PENDING             10010       

【讨论】:

代码正在运行,它为我提供了“field_value”中每个组的所有值,但我无法获得“Work_In_Progress_Date”和“Pending_Date”这两列。我希望最终表包括问题何时是“Work_In_progress”以及何时转移到“待定”。谢谢 您的要求是“我希望表格中的每个值都有一列(例如,产品数量、SKU 上线日期等),并且该列仅包含当天的最后一个值。”所以我知道你每天只想要一张记录。如果您想要所有状态,则只需在查询中更改此行:“last_value(status) over (partition by issue_id, field_time::date order by field_time desc) as last_status”为“status”。 如果向右滚动,在所需的结果中,有两列“Work_In_Progress_Date”和“Pending_Date”每天都应该有一个值,即状态值为 10010 或 10020 的 field_date。那两个我真的不能把它们当作约会对象。感谢您的耐心和帮助。

以上是关于根据雪花中的字段值获取每个日期和数据透视表的最后一个值的主要内容,如果未能解决你的问题,请参考以下文章

MS SQL Server 中的动态数据透视

雪花我们如何遍历临时表的每一行并将其值插入到另一个表中,其中每个字段的值都是单行?

excel查找一段时间内的数据

在雪花中按日期聚合数据组

如何根据数据透视值源字段声明新字段值

VBA:根据单元格值过滤数据透视表