双加"分组"没有加入?

sds*_*sds 3 sql hive

我有用户数据:

user  store  item  cost
1     10     100   5
1     10     101   3
1     11     102   7
2     10     101   3
2     12     103   4
2     12     104   5
Run Code Online (Sandbox Code Playgroud)

我想要一张桌子告诉我每个用户他从每家商店购买了多少以及他总共买了多少钱:

user store  cost_this_store  cost_total
1    10     8                15
1    11     7                15
2    10     3                12
2    12     9                12
Run Code Online (Sandbox Code Playgroud)

我可以用两个group by和一个来做到这一点join:

select s.user, s.store, s.cost_this_store, u.cost_total
from (select user, store, sum(cost) as cost_this_store
      from my_data
      group by user, store) s
join (select user, sum(cost) as cost_total
      from my_data
      group by user) u
on s.user = u.user
Run Code Online (Sandbox Code Playgroud)

然而,如果我用其他任何语言写这个(join显然可以避免,并且两者group by不是独立的),这绝对不是我会这样做的.
是否有可能避免join进入sql

PS.我需要解决方案才能工作hive.

Mic*_*son 6

你可以通过窗口函数来实现这一点...... Hive去年增加了支持:

select distinct
  user, 
  store, 
  sum(cost) over (partition by user, store) as cost_this_store,
  sum(cost) over (partition by user) as cost_total
from my_data
Run Code Online (Sandbox Code Playgroud)

但是,我认为你的原始实现没有任何明显的错误.你基本上有两组不同的数据,你通过它们组合JOIN.

复制可能看起来像是一种不同语言的代码气味,但这不一定是SQL中的错误方法,并且通常你必须采取这样的方法,在两个中间结果集之间复制一部分查询表现原因.

SQL小提琴(SQL Server)

  • @sds我并不特别熟悉Hive,但是`Join`操作本质上是RBDMS的构建方式,并且假设正确的索引,它们以惊人的效率实现.我不担心额外的`join`的开销......即使你确实有窗口函数的选项,它可能会采用与包含`join`的查询类似的执行计划. (3认同)
  • @sds Yea ...如果它能为您提供所需的结果,而且它的运行速度足够快......我会说顺其自然. (2认同)