【问题标题】:Partition by with condition statement使用条件语句进行分区
【发布时间】:2020-07-21 01:32:55
【问题描述】:

我有各个商店销售的产品的数据。对于某些商店,它们以PROMO_FLG 映射的折扣出售。 我想显示两个COUNT PARTITION 列。

+-------------------------+--------------+---------------------+
| Store                   | Item         | PROMO_FLG|
|-------------------------+--------------+---------------------|
| 1                       |            1 |                   0 |
| 2                       |            1 |                   1 |
| 3                       |            1 |                   0 |
| 4                       |            1 |                   0 |
| 5                       |            1 |                   1 |
| 6                       |            1 |                   1 |
| 7                       |            1 |                   1 |
| 8                       |            1 |                   0 |
| 9                       |            1 |                   0 |
| 10                      |            1 |                   0 |
+-------------------------+--------------+---------------------+

首先显示所有有该产品的商店(已完成)

COUNT(DISTINCT STORE) OVER (PARTITION ITEM) 会给出 10

第二个 - 我寻求 - 仅计算在 PROMO_FLG = 1 属性中具有价值的这些商店。

这应该给我们4的价值

【问题讨论】:

    标签: sql database analysis snowflake-cloud-data-platform


    【解决方案1】:

    我想你想要:

    select t.*,
           count(*) over (partition by item) as num_stores,
           sum(promo_flg) over (partition by item) as num_promo_1
    from t;
    

    如果您确实需要不同的计数:

    select t.*,
           count(distinct store) over (partition by item) as num_stores,
           count(distinct case when promo_flg = 1 then store end) over (partition by item) as num_promo_1
    from t;
    

    Here 是一个 dbfiddle。小提琴使用 Oracle 是因为它支持 COUNT(DISTINCT) 作为窗口函数。

    如果窗口功能不起作用,这里有一个替代方法:

    select *
    from t join
         (select item, count(distinct store) as num_stores, count(distinct case when promo_flg = 1 then store end) as num_stores_promo
          from t
          group by item
         ) tt
         using (item);
    

    【讨论】:

    • 谢谢,但是第二个 distinct 不起作用。我得到与第一个 COUNT/PARTITION 相同数量的商店。
    【解决方案2】:

    使用 Gordon 第二个 SQL 但显示它在 Snowflake 中工作

    select v.*
        ,count(distinct store) over (partition by item) as num_stores
        ,count(distinct iff(promo_flg = 1, store, null)) over (partition by item) as num_dis_promo_stores
        ,sum(iff(promo_flg = 1, 1, 0)) over (partition by item) as num_sum_promo_stores
    from values
      (1 , 1, 0 ),
      (2 , 1, 1 ),
      (3 , 1, 0 ),
      (4 , 1, 0 ),
      (5 , 1, 1 ),
      (6 , 1, 1 ),
      (7 , 1, 1 ),
      (8 , 1, 0 ),
      (9 , 1, 0 ),
      (10, 1, 0 )
      v(store, item, promo_flg) ;
    

    给予:

    STORE   ITEM    PROMO_FLG   NUM_STORES  NUM_DIS_PROMO_STORES    NUM_SUM_PROMO_STORES
    1       1       0           10          4                       4
    2       1       1           10          4                       4
    3       1       0           10          4                       4
    4       1       0           10          4                       4
    5       1       1           10          4                       4
    6       1       1           10          4                       4
    7       1       1           10          4                       4
    8       1       0           10          4                       4
    9       1       0           10          4                       4
    10      1       0           10          4                       4
    

    因此,根据您是否需要不同的计数或总和,我使用了雪花支持iff 的非标准 SQL 形式,因为我更喜欢它是更小的 sql。 但是你可以看到它们在工作。

    测试 Gordons 的第二个案例 count(distinct case when promo_flg = 1 then store end) over (partition by item) as num_promo_1 工作正常。

    要回答有关 Gordons 答案的 Marcin2x4 问题,如果/当数据与您描述的方式不同时,您会从方法中获得不同的结果。因此,如果您的商店有一个项目和多行带有 promo_flg 存在。或者如果 promo_flg 具有非零值:

    select v.*
        ,count(distinct store) over (partition by item) as num_stores
        ,count(distinct iff(promo_flg = 1, store, null)) over (partition by item) as num_dis_promo_stores
        ,sum(iff(promo_flg <> 0, 1, 0)) over (partition by item) as num_sum_promo_stores
        ,sum(promo_flg) over (partition by item) as num_promo_1
        ,count(distinct case when promo_flg = 1 then store end) over (partition by item) as num_promo_1
    from values
      (1 , 1, 0 ),
      (2 , 1, 1 ),
      (3 , 1, 0 ),
      (4 , 1, 0 ),
      (5 , 1, 1 ),
      (6 , 1, 1 ),
      (7 , 1, 1 ),
      (8 , 1, 0 ),
      (9 , 1, 0 ),
      (10, 1, 0 ),
      (7, 1, 1 ),
      (7, 1, 2 )
      v(store, item, promo_flg) ;
    

    然后num_dis_promo_stores & num_promo_1 给出 4,num_sum_promo_stores 给出 6,&num_promo_1 给出 7

    【讨论】:

    • 在上述情况下,我追求的是不同数量的部分促销标志的商店。又名,4 家商店 :)
    • 我假设的(我假设 Gordon 也假设),但是您对“相同数字”的评论暗示您可能不知道为什么在有限的数据下您会得到相同的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 2012-04-28
    • 2019-04-06
    • 2021-12-22
    相关资源
    最近更新 更多