2014-01-21 2 views
3

У меня есть пользовательские данные:Двойная «группа» без участия?

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 

Я хочу таблицу, которая будет сказать мне для каждого пользователя, сколько он купил у каждого магазина и сколько он купил в общей сложности:

user store cost_this_store cost_total 
1 10  8    15 
1 11  7    15 
2 10  3    12 
2 12  9    12 

я могу сделать это с двумя 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 

Однако, это, безусловно, не так, как я бы это сделать, если бы я писал этот на любом другом языке (join явно можно избежать, а два group by не являются независимыми).
Можно ли избежать join в sql?

PS. Мне нужно решение для работы в hive.

ответ

6

Вы можете сделать это с windowing function ... который Улей добавил поддержку в прошлом году:

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 

Однако, я бы утверждать, что не было ничего вопиюще неправильно с вашей первоначальной реализации. У вас есть два разных набора данных, которые вы комбинируете через JOIN.

Дублирование может выглядеть как запах кода на другом языке, но это не обязательно неправильный подход в SQL, промежуточные результирующие наборы по соображениям производительности.

SQL Fiddle (SQL Server)

+0

У меня есть улей 0,10, так что, я думаю, я застрял с объединением, не так ли? – sds

+2

@sds Yea ... Если это дает вам результаты, которые вам нужны, и он работает достаточно быстро для вас ... Я бы сказал, пойдите с ним. –

+0

, но он не будет работать «достаточно быстро»! 'join' стоит дорого! – sds

Смежные вопросы