SQL - 将 GROUP BY 与 COUNT DISTINCT PARTITION BY 组合

问题描述 投票:0回答:1

嘿,我想弄清楚这是否可以在一个查询中完成,或者我是否需要使用 CTE,因为 Windows 函数是在分组之后计算的。

原始表:

项目 商店 频道 数量
1/1/24 1 a 1a 在线 4
1/1/24 1 a 1a 亲自 3
1/1/24 1 b 1a 亲自 9
1/7/24 2 b 1a 在线 3
1/7/24 2 b 2a 在线 4
1/7/24 2 b 3a 亲自 3

预期表:

项目 频道 SUM_数量 CNT_DSNT_STR_WEEK_ITEM_CHNL CNT_DSNT_STR_WEEK_ITEM
1 a 在线 4 1 2
1 a 亲自 3 1 2
1 b 亲自 9 1 1
2 b 在线 7 2 3
2 b 亲自 7 1 3

指标:

  • CNT_DSNT_STR_WEEK_ITEM_CHNL - 当数量 > 0 时按周、商品和频道分组时计算不同的商店
  • CNT_DSNT_STR_WEEK_ITEM - 当数量 > 0 时按周和项目分组,对不同的商店进行计数。

我目前正在通过 CTE 执行此操作,以计算周和项目粒度的 CNT_DSNT_STR_WEEK_ITEM,然后将其加入到周、项目、通道粒度中。

当我利用窗口函数进行查询以尝试在一个查询中执行此操作时 - 我会收到错误。这可以在一个查询中完成吗?

错误:

SQL compilation error:
[IFF(QTY > (CAST(0 AS FLOAT)), Stpre, SYSTEM$NULL_TO_FIXED(null))] is not a valid group by expression

查询:

SELECT
   WEEK
    , ITEM
    , CHANNEL
    , SUM(QTY) AS SUM_TY_QTY
    , COUNT(DISTINCT CASE WHEN QTY > 0 THEN STORE END)::INT AS CNT_DSNT_STR_WEEK_ITEM_CHNL
    , COUNT(DISTINCT CASE WHEN QTY > 0 THEN STORE END)
        OVER (PARTITION BY WEEK, ITEM) AS CNT_DSNT_STR_WEEK_ITEM

FROM TABLE
GROUP BY 1, 2, 3
ORDER BY 1;
sql snowflake-cloud-data-platform
1个回答
0
投票

当您执行 OVER 时,您正在定义如何在每行基础上进行窗口化,与高阶 GROUP BY 参考框架相比。因此,

CNT_DSNT_STR_WEEK_ITEM
需要根据上下文融入您在
week, item, channel
组框架中的意图。

这可以通过删除两个聚合值和 group by 子句来看到:

with data(day, week, item, store, channel, qty) as (
    select * from values
    ('1/1/24'::date, 1, 'a', '1a', 'Online',    4),
    ('1/1/24'::date, 1, 'a', '1a', 'In Person', 3),
    ('1/1/24'::date, 1, 'b', '1a', 'In Person', 9),
    ('1/7/24'::date, 2, 'b', '1a', 'Online',    3),
    ('1/7/24'::date, 2, 'b', '2a', 'Online',    4),
    ('1/7/24'::date, 2, 'b', '3a', 'In Person', 3)    
)
SELECT
   WEEK
    , ITEM
    , CHANNEL
    --, SUM(QTY) AS SUM_TY_QTY
    --, COUNT(DISTINCT CASE WHEN QTY > 0 THEN STORE END)::INT AS CNT_DSNT_STR_WEEK_ITEM_CHNL
    , COUNT(DISTINCT CASE WHEN QTY > 0 THEN STORE END) OVER (PARTITION BY WEEK, ITEM) AS CNT_DSNT_STR_WEEK_ITEM
FROM data
--GROUP BY 1, 2, 3
ORDER BY 1;
项目 频道 CNT_DSNT_STR_WEEK_ITEM
1 a 在线 1
1 a 亲自 1
1 b 亲自 1
2 b 在线 3
2 b 在线 3
2 b 亲自 3

您希望它如何与您的 GROUP BY 交互需要解决。因此,如果您的问题是这是否需要在不同的范围层中完成,那么答案是肯定的。

是子选择或 CTE(假设它们在单一使用上下文中相当于同一件事)

© www.soinside.com 2019 - 2024. All rights reserved.