índice
1 Resumo de uso de data no shell
0 Prefácio
Quando fazemos estatísticas de ETL de data warehouse, geralmente precisamos realizar estatísticas em lote nos dados em várias dimensões de tempo, como dia, semana, mês e trimestre. O modo de desenvolvimento geral está na forma de sql no shell, para que possamos executar scripts de shell de acordo com tarefas cronometradas e, ao mesmo tempo, usar o shell para escrever algumas funções para substituir os procedimentos armazenados em SQL. As dimensões de tempo de dia, semana, mês e trimestre neste artigo também são calculadas usando a função de tempo no shell, o que reduz a dificuldade de desenvolvimento de SQL e torna o código mais fácil de manter.
shell中时间的获取常常采用date -d 或date --date来获取
1 Resumo de uso de data no shell
1.1 Gramática básica
1) Gramática básica
data [OPÇÃO] ... [+ FORMATO]
2) Descrição da opção
Tabela 1-20
Opções |
Recursos |
-d <string de tempo> |
Mostra a hora indicada pela "string de hora" especificada em vez da hora atual |
-s <data hora> |
Defina a data e hora do sistema |
3) Descrição do parâmetro
Tabela 1-21
parâmetro |
Recursos |
<+ formato de data e hora> |
Especifique o formato de data e hora usado ao exibir |
1.2 data mostra a hora atual
1) Gramática básica
(1) data (descrição da função: exibir a hora atual)
(2) data +% Y (descrição da função: exibir o ano atual)
(3) data +% m (descrição da função: exibir o mês atual)
(4) data +% d (descrição da função: exibir o dia atual)
(5) data "+% Y-% m-% d% H:% M:% S" (descrição da função: exibir ano, mês, dia, hora, minuto e segundo)
2) Prática de caso
(1) Exibir informações de tempo atual
[root@bigdata-1 ~]# date
2020年 10月 26日 星期一 13:40:45 CST
(2) Exibir a hora atual, ano, mês e dia
[root@bigdata-1 ~]# date +%Y%m%d
20201026
(3) Exibir a hora atual ano, mês, dia, hora, minuto e segundo
[root@bigdata-1 ~]# date "+%Y-%m-%d %H:%M:%S"
2020-10-26 13:42:15
1.3 data exibe hora não atual
1) Gramática básica
(1) data -d '1 dia atrás' (descrição da função: exibir a hora do dia anterior)
(2) data -d'-1 dias atrás '(descrição da função: exibir amanhã, hora)
2) Prática de caso
(1)显示前一天
[root@bigdata-1 ~]# date -d '1 days ago'
2020年 10月 25日 星期日 13:42:45 CST
[root@bigdata-1 ~]# date -d '-1 days'
2020年 10月 25日 星期日 13:43:25 CST
[root@bigdata-1 ~]# date -d 'last day'
2020年 10月 25日 星期日 13:43:51 CST
(2)显示明天时间
[root@bigdata-1 ~]# date -d '1 days'
2020年 10月 27日 星期二 13:44:53 CST
[root@bigdata-1 ~]# date -d '-1 days ago'
2020年 10月 27日 星期二 13:44:28 CST
[root@bigdata-1 ~]# date -d 'next day'
2020年 10月 27日 星期二 13:47:37 CST
(3)指定时间显示
[root@bigdata-1 ~]# date -d '2020-10-26 3 months ago'
2020年 07月 26日 星期日 00:00:00 CST
1.4 data Definir hora do sistema
1) Gramática básica
data -s string hora
2) Prática de caso
(1) Defina a hora atual do sistema
[root@bigdata-1 ~]# date -s "2020-10-26 13:52:18"
2 estatísticas por dia
#!/bin/bash
#1获取时间
lastday=`date --date '-1days' +%F` #获得昨天的日期(今天算昨天的)
if [ "$1" != "" ];then
lastday=$1
fi;
#2定义变量
hive='/usr/idp/current/hive-client/bin/hive';
APP=phmdwdb
input_table="${APP}.输入表名";
output_table="${APP}.输出表名";
#3写SQL
sql="
insert overwrite table ${output_table}
PARTITION (compute_day='${lastday}')
select
,xxx
,xxx
,xxx
from ${input_table}
where compute_day='${lastday}'
...........
...........
;
";
#执行SQL
${hive} -e "${sql}" >>/tmp/${output_table}.log 2>&1 ;
3 estatísticas por semana
#!/bin/bash
#按周统计的表依赖于按天统计的表,因此输入的表为按天统计的表
#1获取时间,每周周一开始算上周的任务
today=`date +%F` #获得当前的日期
start_week=`date -d "${today} -7 days" +%F` #获取上周的周一日期
end_week=`date -d "${today} -1 days" +%F` #获取上周的周末日期
day=`date -d "${today}" +%w` #获取if条件中要匹配的日期
compute_week=`date -d "${start_week}" +%V` #%V:以周一为每周的第一天。%U:以以周日为每星期第一天
if [ "$1" != "" ];then
today=$1
fi;
#2定义变量
hive='/usr/idp/current/hive-client/bin/hive';
APP=phmdwdb
input_table="${APP}.输入表名";
output_table="${APP}.输出表名";
#3写SQL
sql="
insert overwrite table ${output_table}
PARTITION (compute_week='${compute_week}')
select
,xxx
,xxx
,xxx
from ${input_table}
where compute_day>='${start_week}' and compute_day<'${today}' --注意按周分析的依赖于按天统计的表,所以用compute_day
...........
...........
;
";
#执行SQL
if [ ${day} == '1' ];then
${hive} -e "${sql}" >>/tmp/$log_dir.log 2>&1 ;
else
echo '只有在周一计算上一周的统计值';
fi
4 estatísticas mensais
#!/bin/bash
#按月统计的表依赖于按天统计的表,因此输入的表为按天统计的表
#1获取时间,每月初开始算上月的任务
today=`date +%Y-%m-%d` #获得当前的日期
start_date=`date -d "${today} -1 days " +%Y-%m-01` #获得上个月月初的时间
end_date=`date -d"${today} last day" +%Y-%m-%d` #上个月最后一天
day=`date -d "${today}"+%d`; #获取当前需要匹配的时间.(只有月初的时候才会计算,月初时获取天值为01)
compute_month=`date -d ${start_date} +%Y-%m`; #获取静态分区的指定健值。计算的是上个月。
if [ "$1" != "" ];then
today=$1
fi;
#2定义变量
hive='/usr/idp/current/hive-client/bin/hive';
APP=phmdwdb
input_table="${APP}.输入表名";
output_table="${APP}.输出表名";
#3写SQL
sql="
insert overwrite table ${output_table}
PARTITION (compute_month='${compute_month}')
select
,xxx
,xxx
,xxx
from ${input_table}
where compute_day>='${start_date}' and compute_day<'${today}' --注意按月分析的依赖于按天统计的表,所以用compute_day
...........
...........
;
";
#执行SQL.月的时候匹配的是01
if [ ${day} == '01' ];then
${hive} -e "${sql}" >>/tmp/$log_dir.log 2>&1 ;
else
echo '只有在月初计算上一月的统计值';
fi
5 estatísticas por trimestre
Nota: Este script usa a operação de divisão do shell ao contar, e a divisão do shell é feita com a calculadora bc, onde a escala é o número de casas decimais e há espaços em ambos os lados. Quando o shell calcula adição, subtração, multiplicação e divisão, se for uma operação inteira, $ ((a + b)) ou $ [a + b] é geralmente usado. Se for uma operação decimal, a calculadora bc é geralmente usado para cálculos, e o controlador de escala tem o número de casas decimais.
#!/bin/bash
#按季度统计的表依赖于按月统计的表,因此输入的表为按月统计的表
#1获取时间,每季度初开始算上季度的任务
today=`date +%F` #获取当前的日期
current_month=`date -d "${today}" +%Y-%m` #获取当前的月份
start_month=`date -d "${today} 3 month ago" +%Y-%m` #获取季度开始的月份
end_month=`date -d "${today} -1 month" +%Y-%m` #获取季度结束的月份
match=`date -d "${today}" +%m` #获取条件需要匹配的值
temp=`date -d ${start_quarter}_01 +%m` #获取上一季度开始的月份数字,作为中间结果值
compute_quarter=`echo "scale=0; (${temp}-1) / 3 + 1" | bc` # 计算静态分区的健值,季度值。按月份求季度的算法。
if [ "$1" != "" ];then
today=$1
fi;
#2定义变量
hive='/usr/idp/current/hive-client/bin/hive';
APP=phmdwdb
input_table="${APP}.输入表名";
output_table="${APP}.输出表名";
#3写SQL
sql="
insert overwrite table ${output_table}
PARTITION (compute_quarter='${compute_quarter}')
select
,xxx
,xxx
,xxx
from ${input_table}
where compute_month>='${start_month}' and compute_month<'${current_month}' --注意按季度分析的依赖于按月统计的表,所以用compute_month
...........
...........
;
";
#执行SQL.季度的时候匹配的是01,04,07,10.每过一季度统计一次
if [ ${match} == '01' ]; then
${hive} -e "set mapred.job.name=统计第四季度;${sql}" >>/tmp/$log_dir.log 2>&1;
elif [ ${match} == '04' ]; then
${hive} -e "set mapred.job.name=统计第一季度;${sql}" >>/tmp/$log_dir.log 2>&1;
elif [ ${match} == '07' ]; then
${hive} -e "set mapred.job.name=统计第二季度;${sql}" >>/tmp/$log_dir.log 2>&1;
elif [ ${match} == '10' ]; then
${hive} -e "set mapred.job.name=统计第三季度;${sql}" >>/tmp/$log_dir.log 2>&1;
else
echo '只有等到季度初的时候才进行统计';
fi
6 Resumo
Vários modelos de desenvolvimento de código neste artigo também são usados com frequência em estatísticas ETL reais. O artigo resume vários códigos de estatísticas de dimensão de tempo comuns em data warehouses e os abstrai em modelos para referência e uso dos leitores.