Как рассчитать самое популярное устройство, ОС, браузер в каждом городе в HiveQL? - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть таблица со строками агента пользователя (которую я разбираю в столбцы browser, os и device) и города id.Я хочу вычислить самые популярные browser, os и device для каждого city.

Вот моя попытка:

select device os, browser, name, MAX(hits) as pop from 
(select uap.device, uap.os, uap.browser, name, COUNT(*) as hits 
from (select * from browserdata join citydata on cityid=id) t 
lateral view ParseUserAgentUDTF(UserAgent) uap as device, os, browser 
GROUP BY uap.device, uap.os, uap.browser, name) t2 
GROUP BY name;

Итак, самый внутренний подзапрос,aliased t просто присоединяет мою таблицу к другой таблице, которая отображает id в город name s, поэтому я могу видеть фактические name s вместо city id в выходных данных.

Затем подзапрос с именем t2 подсчитывает количество составных ключей (device, browser, os, city).А внешний запрос группирует все в name окнах и извлекает строку с максимальным количеством пользователей.

Я получаю следующую ошибку:

FAILED: SemanticException [Ошибка 10025]: Строка 1: 7 Выражение отсутствует в ключе GROUP BY 'устройство'

Я понимаю, что это значит.Он говорит, что мне нужно включить device в group by, но если я это сделаю, то он не будет вычислять то, что я хочу.Как мне исправить мой запрос?

Кроме того, я заметил, что некоторые из моих запросов к кустам выполняются на mapreduce, но не на tez.Почему это?

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Используя аналитические функции, вы можете исключить ненужные объединения:

WITH 
t1 as 
(select * from browserdata join citydata on cityid=id),

t2 as 
(select uap.device as device, uap.os as os, uap.browser as browser, name as cityname 
from t1 
lateral view ParseUserAgentUDTF(UserAgent) uap as device, os, browser),

t3 as
(select t2.cityname as cityname, t2.device as device, t2.browser as browser, t2.os as os, count(*) as count from t2 group by t2.cityname, t2.os, t2.device, t2.browser)

select cityname, maximum,  device, os, browser
 from
     (select cityname, device, browser, os, 
             max(count) over(partition by cityname)                         as maximum,
             dense_rank() over (partition by cityname order by count desc ) as rnk      
      from t3
     ) s  where rnk =1 
;
0 голосов
/ 24 декабря 2018
WITH t1 as 
(select * from browserdata join citydata on cityid=id),

t2 as 
(select uap.device as device, uap.os as os, uap.browser as browser, name as cityname 
from t1 
lateral view ParseUserAgentUDTF(UserAgent) uap as device, os, browser),

t3 as
  (SELECT t2.cityname as cityname, t2.device as device, t2.browser as browser, t2.os as os, COUNT(*) as count FROM t2 GROUP BY t2.cityname, t2.os, t2.device, t2.browser),

t4 as
    (select cityname, MAX(count) as maximum from t3 group by cityname)

select t4.cityname, t4.maximum, t3.device, t3.os, t3.browser
from t4 join t3 on t4.cityname=t3.cityname and t4.maximum=t3.count;

Это работает, однако мне интересно, есть ли способ его оптимизировать ...

...