我们在做统计的时候可以会遇到一条hive语句解决不了的事情,需要执行php,python等脚本语言来辅助
在工作中遇到一个同恰到的需求,而签到的信息是存放在mybaby_tblappucloud表的ext字段 在ext的存在形式是{checkin:{201504:3,201503:8}}
其中key 201504对应value是3,我们的签到信息是通过位来存储3转换为二进制为11 代表4月份第一天和第二天都签到了
那么需求来了:统计4月分签到1天,2天,三天,4...............30天的有多少人?
这个需求直接用hive无法做,所有通过hive调用php脚本
select tmp.day,count(tmp.day)
(SELECT
hk_ext['checkin'] --将选择出来的签到信息,一条条输入到 dealCheckin.php
USING
'${hiveconf:HDFS_PHP} dealCheckin.php'
AS
(day BIGINT)
FROM
mybaby_tblappucloud
WHERE
dt = '{@date}'
AND hk_ext['checkin'] IS NOT NULL
) tmp group by tmp,day;
dealCheckin.php如下:
<?php
/***************************************************************************
*
* Copyright (c) 2015 Baidu.com, Inc. All Rights Reserved
*
**************************************************************************/
/**
* @file dealCheckin.php
* @author jiangzeyun
* @date 2015/04/13 19:28:55
* @brief
*
**/
ini_set("error_reporting",E_ALL & ~E_NOTICE);
ini_set("display_errors","off");
ini_set("max_execution_time",0);
ini_set("memory_limit","10240M");
ini_set('date.timezone','Asia/Shanghai');
$strNowMon = date('Ym',time());
$result=array();
$fp = fopen('php://stdin', 'r');
while($line = trim(fgets($fp))) {
$checkin = strval(urldecode($line));
$checkin = @json_decode($checkin, true);
if(isset($checkin[$strNowMon]))
{
$totalDays = countOneInBinary(intval($checkin[$strNowMon]));
print $totalDays."\n";
}
}
/*
* @brief 计算正数二进制表示时1的个数
* @author jiangzeyun
* @思路: 利用 n & (n - 1) 可以将最后一个1变0,重复直到为0
* @date 2015-03-11
*/
function countOneInBinary($int) {
$num = 0;
if ($int <= 0) {
return $num;
}
while ($int != 0) {
$num++;
$int &= ($int - 1);
}
return $num;
}