hive实战12--时间占比和上一小时逻辑

目录

一:已知表结构和字段

二:需求1:时间占比

三:需求2--目前小时与上一小时比较

四:使用窗口函数lag()解决需求三

五:只存储电脑每天最后一次更新的时间对应的信息


一:已知表结构和字段

    某电脑售卖数据表computer,从左至右依次为location,店铺ID,某天,某小时,某分钟,商品是否到期,商品的存量,商品卖出的数量,商品进货数量/

location ID pt_day pt_hour pt_minute good_computer computer_store computer_out computer_in update_time
0到23 0到59

1代表正常

0代表坏

存量 销售量 进货量

二:需求1:时间占比

查询北京东城区的所有店铺在2021-01-11全天缺正常电脑时段占比,全天(除去凌晨0:00-6:00)缺正常电脑时段占比,上午(07:30-10:00)缺正常电脑占比。

提示:分子/分母

分子:每个店铺id在某天的正常电脑数量数为0时的分钟数有多少个(eg. 全天24h内,有X个分钟时段的存量车数为0,则分子为X)分母:全天总分钟数(24 * 60)

思路解析:

  • 7:30--10:00如何写逻辑:方法1: 分情况,当pt_hour = 7的时候再进一步判断pt_minute的大小;方法2:把小时*60换算成分钟再加上分钟的数据形成一个数,然后再进行判断。
  • 统计中有多个指标,且约束互补相同,使用case when进行统计。
  • sum(case when ... then 1 else 0 end)和count(case when ... then 1 else 0 end)的区别:sum(case when ..)才是正确的用法,他会把case when中为1的累加起来,而count(case when..)不管case when的情况是1还是0都会被count一次,所以不起作用。
  • 注意有很对关键字在命名或者select的时候要注意:例如minute, all这些字段。

代码:注意表里面的粒度都已经到分钟了。

select id ,
       count(1)/(24*60) as a1,   -- 24*60这个整体用括号括起来,细心一点
       sum(case when(pt_hour>=0 and pt_hour<6) then 1 else 0 end)/(6*60) as a2,
       sum(case when pt_hour*7+pt_minute > 7*60+30 and pt_hour<10 then 1 else 0 end) as a3
       -- sum(case when (pt_hour = 7 and pt_minute <30) or (pt_hour >=8 and pt_hour<10) then 1 else 0 end ) as a3
from computer
where pt_day = '2021-01-11'
    and good_computer = 1
    and location = "北京市东城区"
group by id
order by id

三:需求2--目前小时与上一小时比较

查询北京东城区的所有店铺在2021-01-11全天每个店铺,以每1小时为分时段的销售正常电脑量,进货正常电脑量,存量,现在时段销售订单/上一分钟时段存量车数。

思路解析:

  • 当前小时和上一小时的逻辑
  • 当天的凌晨第一个小时的上一个小时要去前一天的第23小时以后取。所以我们可以单独考虑,最后使用union all即可。
  • 表和自身表做连接,千万要注意:每个表都要用时间去约束,千万不要取全量,不仅速度满,结果还是错误的。

代码:

select c5.id, 
       c5.computer_out,
       c5.computer_in,
       c5.computer_store,
       c5.ration
(
select c1.id as id,
     c1.computer_out as computer_out, 
     c1.computer_in as computer_in , 
     c1.computer_store as computer_store, 
     c1.computer_out / c2.store as ration
from computer c1
left outer join computer c2
on c1.id = c2.id
where c1.pt_day = '2021-01-11'
   and c2.pt_day = '2021-01-11'   -- 此条逻辑别忘了
   and c1.pt_hour= c2.pt.hour+1
   and location = ' 北京市东城区'
   
union all

select c3.id as id,
     c3.computer_out as computer_out, 
     c3.computer_in as computer_in , 
     c3.computer_store as computer_store, 
     c3.computer_out / c4.store as ration
from computer c3
left outer join computer c4
on c3.id = c4.id
where c3.pt_day = '2021-01-11'
   and c4.pt_day = '2021-01-10'   -- 此条逻辑别忘了
   and c3.pt_hour= 0
   and c4.pt_hour = 23
   and c3.location = ' 北京市东城区'
   and c4.location = '北京市东城区' --此条也需要吧!!
) c5
group by c5.id 
order by c5.id, c5.pt_hour;

四:使用窗口函数lag()解决需求三

ing 

五:只存储电脑每天最后一次更新的时间对应的信息

 思路:

  •     最后一次更新如何求:把更新时间排序一下,注意从大到小排序,然后外层循环中每次取第一名。
select 
food_id,
otehr,
update_time,
dt
from
(
	select
	id,
	row_number() over(partition by food_id order by update_time desc) as r,
    other,
	update_time,
	dt
	from computer
	where pt_day = '2021-01-11'
) temp_table 
where r = 1;

上一篇:Mysql 主从延时监控(pt-heartbeat)


下一篇:R语言 t分布(不同*度)