首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在雪花sql中用分区和order来计数不同的值?

如何在雪花sql中用分区和order来计数不同的值?
EN

Stack Overflow用户
提问于 2020-12-09 01:50:47
回答 3查看 832关注 0票数 1

我的数据如下:

代码语言:javascript
复制
| user | eventorder| postal|
|:---- |:---------:| -----:|
| A    | 1         | 60616 |
| A    | 2         | 10000 |
| A    | 3         | 60616 |
| B    | 1         | 20000 |
| B    | 2         | 30000 |
| B    | 3         | 40000 |
| B    | 4         | 30000 |
| B    | 5         | 20000 |

--我需要解决的问题:在每个事件订购之前,用户需要停多少个不同的站点?

理想的结果如下:

代码语言:javascript
复制
| user | eventorder| postal| travelledStop|
|:---- |:---------:| -----:| ------------:|
| A    | 1         | 60616 |  1    |
| A    | 2         | 10000 |  2    |
| A    | 3         | 60616 |  2    |
| B    | 1         | 20000 |  1    |
| B    | 2         | 30000 |  2    |
| B    | 3         | 40000 |  3    |
| B    | 4         | 30000 |  3    |
| B    | 5         | 20000 |  3    |

以A为例,当事件顺序为1时,它只行驶了60616 - 1站.当事件顺序为2时,它已经行驶了60616站和10000 - 2站.当事件顺序为3时,此用户所走过的不同停止为60616和10000。-2站。

我不允许使用和order分区。我想做这样的事情,如计数(不同(邮政))在(按用户订单按事件顺序分区),但这是不允许的。

有人知道怎么解决这个问题吗?非常感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-12-09 03:42:30

也许最简单的方法是使用子查询并计算“1”:

代码语言:javascript
复制
select t.*,
       sum(case when seqnum = 1 then 1 else 0 end) over (partition by usr order by eventorder) as num_postals
from (select t.*,
             row_number() over (partition by usr, postal order by eventorder) as seqnum
      from t
     ) t
票数 0
EN

Stack Overflow用户

发布于 2020-12-09 02:58:46

我使用了您提供的样本数据(只是A的子集,但这应该是扩展的)。这里的目标实际上是为每一行生成一个数组,该数组累加前一个事件的所有that。

代码语言:javascript
复制
with _temp as (
select 'A' as usr, 1 as EventOrder, '60616' as Postal
UNION ALL
select 'A' as usr, 2 as EventOrder, '10000' as Postal
UNION ALL
select 'A' as usr, 3 as EventOrder, '60616' as Postal
),
_intermediate as (
select usr
    , eventorder
    , postal
    , array_slice(
          array_agg(postal)
            within group (order by eventorder)
            OVER (Partition by usr)
           , 0, eventorder) as full_array
from _temp
group by usr, eventorder, postal
)
select usr, eventorder, postal, count(distinct f.value)
from _intermediate i, lateral flatten(input => i.full_array) f
group by usr, eventorder, postal
票数 1
EN

Stack Overflow用户

发布于 2020-12-09 03:43:53

我喜欢@Daniel Zagales的回答,但是这里有一个使用dense_ranksum的方法。

代码语言:javascript
复制
with temp as (
select 'A' as usr, 1 as EventOrder, '60616' as Postal
UNION ALL
select 'A' as usr, 2 as EventOrder, '10000' as Postal
UNION ALL
select 'A' as usr, 3 as EventOrder, '60616' as Postal  
UNION ALL
select 'B' as usr, 1 as EventOrder, '20000' as Postal  
UNION ALL
select 'B' as usr, 2 as EventOrder, '30000' as Postal  
UNION ALL
select 'B' as usr, 3 as EventOrder, '40000' as Postal 
UNION ALL
select 'B' as usr, 4 as EventOrder, '30000' as Postal  
UNION ALL
select 'B' as usr, 5 as EventOrder, '20000' as Postal 
),
temp2 as(
select temp.* ,dense_rank()over(partition by usr,Postal order by EventOrder) rks
from temp 
)
select usr,eventorder,postal,sum(case when rks = 1 then 1 else 0 END)over(partition by usr order by EventOrder) travelledStop
from temp2 
order by usr,EventOrder 

主要是用dense_rank来得到第一次出现,停止而不是总结。

db<>fiddle

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65209513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档