Aplicaciones típicas de las funciones de análisis en Hive

todo el mundo:

  ¡es bueno! Hoy vi una pregunta sobre la función de análisis de colmena, que es muy interesante. Ordené las respuestas y las compartí, con la esperanza de ser útil para todos. Los requisitos son los siguientes:

   Cuando vi esta pregunta por primera vez, sentí que debería usarse la función de análisis, pero no sabía cómo usarla. Afortunadamente, al final, se escribió, y la idea es la siguiente:

---- La estructura de la tabla y los datos de la tabla de prueba son los siguientes:

hive> desc sales;
OK
id                   int                                    
produce_name         string                                  
start_time           date                                    
end_time             date                                    
days                 int                                    
Time taken: 0.354 seconds, Fetched: 5 row(s)
hive> select * from sales;
OK
1 nike 2011-09-01 2011-09-05 5
2 nike 2011-09-03 2011-09-06 4
3 nike 2011-09-09 2011-09-15 7
4 oppo 2011-08-04 2011-08-05 2
5 oppo 2011-08-04 2011-08-15 12
6 vivo 2011-08-15 2011-08-21 7
7 vivo 2011-09-02 2011-09-12 11
Time taken: 0.223 seconds, Fetched: 7 row(s)


--- Paso 1: Encuentre la hora de inicio y la hora de finalización de la promoción anterior para cada hora de inicio

select id,produce_name,start_time,end_time,
lag(start_time) over(partition by produce_name order by id) before_start_time,
lag(end_time) over(partition by produce_name order by id) before_end_time
from sales;


--- El primer paso: resultado de la ejecución (primer paso)

1 nike 2011-09-01 2011-09-05 NULL NULL
2 nike 2011-09-03 2011-09-06 2011-09-01 2011-09-05
3 nike 2011-09-09 2011-09-15 2011-09-03 2011-09-06
4 oppo 2011-08-04 2011-08-05 NULL NULL
5 oppo 2011-08-04 2011-08-15 2011-08-04 2011-08-05
6 vivo 2011-08-15 2011-08-21 NULL NULL
7 vivo 2011-09-02 2011-09-12 2011-08-15 2011-08-21


--- Paso 2 De acuerdo con la hora de inicio y la hora de finalización de la promoción anterior, la hora de inicio se unifica como la más temprana, en preparación para la siguiente agrupación

select produce_name,start_time,max(end_time) end_time from 
(select id,produce_name,case when start_time>=before_start_time and start_time<=before_end_time then before_start_time else start_time end as start_time, end_time
from (select id,produce_name,start_time,end_time,
lag(start_time) over(partition by produce_name order by id) before_start_time,
lag(end_time) over(partition by produce_name order by id) before_end_time
from sales) t) d
group by produce_name,start_time;


- El resultado de la ejecución del segundo paso (el segundo paso)

nike 2011-09-01 2011-09-06
nike 2011-09-09 2011-09-15
oppo 2011-08-04 2011-08-15
vivo 2011-08-15 2011-08-21
vivo 2011-09-02 2011-09-12


--- Paso 3 De acuerdo con la hora de inicio combinada, calcule la suma de los días de promoción en cada período de tiempo

select produce_name,start_time,end_time,datediff(end_time,start_time)+1 days from
(select produce_name,start_time,max(end_time) end_time from 
(select id,produce_name,case when start_time>=before_start_time and start_time<=before_end_time then before_start_time else start_time end as start_time, end_time
from (select id,produce_name,start_time,end_time,
lag(start_time) over(partition by produce_name order by id) before_start_time,
lag(end_time) over(partition by produce_name order by id) before_end_time
from sales) t) d
group by produce_name,start_time) e;


- Resultado de la ejecución (el tercer paso)

nike 2011-09-01 2011-09-06 6
nike 2011-09-09 2011-09-15 7
oppo 2011-08-04 2011-08-15 12
vivo 2011-08-15 2011-08-21 7
vivo 2011-09-02 2011-09-12 11

--Paso 4: según el nombre del producto, encuentre la suma de los días de promoción finales

select produce_name,sum(days) from
(select produce_name,start_time,end_time,datediff(end_time,start_time)+1 days from
(select produce_name,start_time,max(end_time) end_time from 
(select id,produce_name,case when start_time>=before_start_time and start_time<=before_end_time then before_start_time else start_time end as start_time, end_time
from (select id,produce_name,start_time,end_time,
lag(start_time) over(partition by produce_name order by id) before_start_time,
lag(end_time) over(partition by produce_name order by id) before_end_time
from sales) t) d
group by produce_name,start_time) e) f
group by produce_name;


--- Resultado de la ejecución (cuarto paso)
 

nike 13
oppo 12
vivo 18

 

Descripción: Opinión personal, ¡espero que sea de ayuda para todos!

Después de un análisis posterior, este método tiene problemas, si el valor continuo involucra múltiples filas, habrá un problema al tomar el valor mínimo según el offset.

El primer paso es obtener la última hora de finalización de cada fila.

select id,
produce_name,
start_time,
end_time,
lag(end_time,1,start_time) over(partition by produce_name order by id) before_end_time
from sales

El efecto es el siguiente:

 

El segundo paso es calcular el número de días entre la hora de inicio y la última hora de finalización del banco. Debido a que la función dateiff es un concepto de diferencia, el valor continuo debe aumentarse en 1 y el número de días en el intervalo debe restarse en 1.

select 
id,
produce_name,
end_time,
start_time,
before_end_time,
datediff(end_time,start_time)+1 as cnt_all,
case when start_time<=before_end_time then 0 else datediff(start_time,before_end_time)-1 end cnt 
from (select id,
produce_name,
start_time,
end_time,
lag(end_time,1,start_time) over(partition by produce_name order by id) before_end_time
from sales ) t

El efecto es el siguiente:

 

El resultado está en línea con la conjetura: la hora de inicio de la tercera línea de Nike es la novena y la última vez que terminó es la sexta, hay una diferencia de 2 días en el medio.

El tercer paso es sumar el valor continuo y el valor del intervalo intermedio de acuerdo con el resumen del producto.

select 
produce_name,
min(start_time) as start_time,
max(end_time) as end_time,
datediff(max(end_time),min(start_time))+1 cnt_all,
sum(case when start_time<=before_end_time then 0 else datediff(start_time,before_end_time)-1 end) cnt 
from (select id,
produce_name,
start_time,
end_time,
lag(end_time,1,start_time) over(partition by produce_name order by id) before_end_time
from sales ) t 
group by produce_name

El resultado es el siguiente:

El cuarto paso es el guión final, simplificado.

select 
produce_name,
datediff(max(end_time),min(start_time))+1-
    sum(case when start_time<=before_end_time then 0 else datediff(start_time,before_end_time)-1 end) cnt 
from (select id,
produce_name,
start_time,
end_time,
lag(end_time,1,start_time) over(partition by produce_name order by id) before_end_time
from sales ) t 
group by produce_name

El resultado final es el siguiente:

 

      Opinión personal, por favor corríjame.

 

Supongo que te gusta

Origin blog.csdn.net/zhaoxiangchong/article/details/78523589
Recomendado
Clasificación