Snowflake Replace 加入 group by 单连接子句

Snowflake Replace to joins with group by clause with single join

我必须将 LATEST CLICK 作为点击 Event_Type 的 ID 的最新日期。对 Event_Type = 'open' 做类似的事情。我有这样的数据:

Id Event_Type SRC_CREATED
1 click 2021-04-10 01:50:08.490
1 click 2021-03-10 02:221:05.115
1 open 2021-06-10 01:12:08.288
1 click 2021-08-10 01:50:08.490

要求的结果:

Id Event_Type SRC_CREATED
1 click 2021-08-10 01:50:08.490
1 open 2021-06-10 01:12:08.288

我使用了下面提到的查询,它工作正常,但我想用单个连接替换 2 个以某种方式使用的连接来获取这两个数据。谁能想出解决方法?

CREATE OR REPLACE table CUSTOMER AS
select CONCAT(NVL(ADD1,''),NVL(ADD2,'')) AS ADDRESS,
    CASE
WHEN NVL(GENDER,'')='F' THEN 'Female'
WHEN NVL(GENDER,'')='M' THEN 'Male'
WHEN NVL(GENDER,'')='U' Then 'Other'
ELSE ''
END AS GENDER,
***CLICK AS LAST_CLICK,
OPENS AS LAST_EMAIL_CLICK,***
B.PHONE AS PHONE,
A.SRC_CREATED AS SINCE,
from "HXP_SANDBOX"."BASE_RA_TEST"."IDENTITY" A
inner join "HXP_SANDBOX"."BASE_RA_TEST"."EMAIL_INTERACTIONS" B
on A.DIGITALID = B.DIGITALID 
***inner JOIN (SELECT DIGITALID,MAX(SRC_CREATED) CLICK
 from "HXP_SANDBOX"."BASE_RA_TEST"."EMAIL_INTERACTIONS" t
  where EVENT_TYPE = 'click'
 group by DIGITALID) C
on A.DIGITALID = C.DIGITALID
inner JOIN (SELECT DIGITALID,MAX(SRC_CREATED) OPENS
 from "HXP_SANDBOX"."BASE_RA_TEST"."EMAIL_INTERACTIONS" t
  where EVENT_TYPE = 'open'
 group by DIGITALID) D
on A.DIGITALID = D.DIGITALID;***

您应该能够执行以下操作,在 MAX 中使用 CASE 将其限制为您想要的事件类型。

CREATE OR REPLACE TABLE CUSTOMER
AS
SELECT CONCAT(NVL(ADD1,''), NVL(ADD2,'')) AS [ADDRESS]
    , CASE
        WHEN NVL(GENDER,'')='F' THEN 'Female'
        WHEN NVL(GENDER,'')='M' THEN 'Male'
        WHEN NVL(GENDER,'')='U' Then 'Other'
        ELSE ''
    END AS GENDER
    , C.CLICK AS LAST_CLICK
    , C.OPENS AS LAST_EMAIL_CLICK
    , B.PHONE AS PHONE
    , A.SRC_CREATED AS SINCE
FROM "HXP_SANDBOX"."BASE_RA_TEST"."IDENTITY" A
INNER JOIN "HXP_SANDBOX"."BASE_RA_TEST"."EMAIL_INTERACTIONS" B ON A.DIGITALID = B.DIGITALID 
INNER JOIN (
    SELECT DIGITALID
      , MAX(CASE WHEN EVENT_TYPE = 'click' THEN SRC_CREATED ELSE NULL END) CLICK
      , MAX(CASE WHEN EVENT_TYPE = 'open' THEN SRC_CREATED ELSE NULL END) OPENS
    FROM "HXP_SANDBOX"."BASE_RA_TEST"."EMAIL_INTERACTIONS" t
    GROUP BY DIGITALID
) C ON A.DIGITALID = C.DIGITALID;

使用此 CTE 提供数据

    SELECT column1 as id, column2 as event_type, to_timestamp(column3) as src_created
    FROM VALUES
    (1,'click','2021-04-10 01:50:08'),
    (1,'click','2021-03-10 02:21:05'),
    (1,'open','2021-06-10 01:12:08'),
    (1,'click','2021-08-10 01:50:08')
)

以下SQL给出了你想要的答案:

SELECT
    id
    ,event_type 
    ,max(src_created)
FROM fake_data
GROUP BY 1,2
ORDER BY 1,2;

给出:

ID EVENT_TYPE MAX(SRC_CREATED)
1 click 2021-08-10 01:50:08.000
1 open 2021-06-10 01:12:08.000

但是 你要求的不是你的 SQL 所做的,Dale 的回答显示了如何做到这一点。

这与我的示例数据中的相同:

SELECT
    id
    ,max(iff(event_type='click', src_created, null)) as last_click
    ,max(iff(event_type='open', src_created, null)) as last_click
FROM fake_data
GROUP BY 1

您可以使用 CASE 或 IFF,我更喜欢 IFF,因为它更短、更明确。如果您要使用 CASE 路径,则可以删除 ELSE NULL,因为这是默认行为。

因此 Dale 的示例可以是:

  ,MAX(CASE WHEN event_type = 'click' THEN src_createdEND) AS click
  ,MAX(CASE WHEN event_type = 'open' THEN src_createdEND) AS opens
``