業務場景:
現在有一個需求,需要計算出我們數據中每個季度的、每個月的、每週一到週日的、節假日、休息日、工作日的數據指標。
此時節假日、休息日、工作日並不能使用SQL直接計算出來,所以我們可以先搞出一張存儲着這個日期是否爲節假日、休息日、工作日的這樣一張日期類型表。然後在在與業務數據表進行一個Join不就有結果了嗎。
所以日期類型表具體字段看👇圖:
字段名 | 類型 | 示例值 | 描述 |
---|---|---|---|
date_key | string | 20000101 | 代理鍵 |
date_value | string | 2000-01-01 | 年-月-日 |
day_in_year | string | 1 | 當年的第幾天 |
day_in_month | string | 1 | 當月的第幾天 |
is_first_day_in_month | string | y | 是否月的第一天 |
is_last_day_in_month | string | n | 是否月的最後一天 |
weekday | string | 星期一 | 星期幾 |
week_in_month | string | 1 | 月的第幾個星期 |
is_first_day_in_week | string | y、n | 是否週一 |
is_dayoff | string | y、n | 是否休息日 |
is_workday | string | y、n | 是否工作日 |
is_holiday | string | y、n | 是否國家法定節假日 |
date_type | string | workday、weekend、holiday 工作日、週末、法定節假日 | 日期類型 工作日:workday 國家法定節假日:holiday 休息日:weekend |
month_number | string | 1、2、..、12 | 月份 |
year | string | 2000 | 年份 |
quarter_name | string | Q1 | 季度名稱 |
quarter_number | string | 1 | 季度 |
year_quarter | string | 2000-Q1 | 年-季度 |
year_month_number | string | 2000-01 | 年-月份 |
開始實現:
一:下載安裝Kettle工具
安裝Kettle之前必須確保已經安裝了Java JDK,因爲Ketttle是使用Java語言發開的【JDK安裝自行百度】。
官網下載穩定版本 地址【傳送門】
免安裝-開箱即用:
選擇 Spoon.bat雙擊即可運行 (可以創建一個快捷方式發送到桌面)
歡迎首界面
二、創建一個轉換
編輯生成記錄
編輯增加序列從0開始,每次累加1
編寫JavaScript腳本
//Script here
// 1. 初始化上游變量
var initDateStr = "2019-01-01";
var locale = new java.util.Locale("en", "us");
var calendar = java.util.Calendar.getInstance();
var sdf = new java.text.SimpleDateFormat("yyyy-MM-dd", locale);
var initDate = sdf.parse(initDateStr);
calendar.setTime(initDate);
calendar.add(java.util.Calendar.DAY_OF_MONTH, oneDay);
var curDate = calendar.getTime();
// 2. 生成維度數據
// 2.1 生成代理鍵
sdf.applyPattern("yyyyMMdd");
var date_key = sdf.format(curDate);
// 2.2 年-月-日
sdf.applyPattern("yyyy-MM-dd");
var date_value = sdf.format(curDate);
// 2.3 當年的第幾天
var day_in_year = calendar.get(java.util.Calendar.YEAR) + "";
// 2.4 當月的第幾天
var day_in_month = calendar.get(java.util.Calendar.DAY_OF_MONTH) + "";
// 2.5 是否爲當月的第一天
var is_first_day_in_month = day_in_month.equals("1") ? "y":"n";
// 2.6 是否爲當月最後一天
// 1. 加一天
calendar.add(java.util.Calendar.DAY_OF_MONTH, 1);
var is_last_day_in_month = calendar.get(java.util.Calendar.DAY_OF_MONTH) == 1 ? "y":"n";
// 2. 減回去
calendar.add(java.util.Calendar.DAY_OF_MONTH, -1);
// 2.7 星期
var weekday = (calendar.get(java.util.Calendar.DAY_OF_WEEK) - 1) + "";
if(weekday.equals("0")) {
weekday = "7";
}
// 2.8 月的第幾個星期
sdf.applyPattern("W");
var week_in_month = sdf.format(curDate);
// 2.9 是否週一
var is_first_day_in_week = calendar.get(java.util.Calendar.DAY_OF_WEEK) == java.util.Calendar.MONDAY ? "y":"n";
// 2.10 是否休息日
var is_dayoff = "n";
// 2.11 是否工作日
var is_workday = "n";
// 2.12 是否國家法定節假日 從國務院提供的API中獲取
var is_holiday = "n";
// 2.12 國家法定節假日獲取URL
var holiday_url = "http://wow.kamisamak.com/api.php?date="+date_value
// 2.13 日期類型
var date_type = "workday";
// 2.14 月份
sdf.applyPattern("MM");
var month_number = sdf.format(curDate);
// 2.15 年份
sdf.applyPattern("yyyy");
var year = sdf.format(curDate);
// 2.16 年份-月份
sdf.applyPattern("yyyy-MM");
var year_month_number = sdf.format(curDate);
// 2.16 季度名稱、季度、年季度
var quarter_name = "";
var quarter_number = "";
var year_quarter = "";
switch (calendar.get(java.util.Calendar.MONTH)) {
case java.util.Calendar.FEBRUARY:
case java.util.Calendar.JANUARY:
case java.util.Calendar.MARCH:
quarter_name = "Q1";
quarter_number = "1";
year_quarter = year + "-" + quarter_name;
break;
case java.util.Calendar.APRIL:
case java.util.Calendar.MAY:
case java.util.Calendar.JUNE:
quarter_name = "Q2";
quarter_number = "2";
year_quarter = year + "-" + quarter_name;
break;
case java.util.Calendar.JULY:
case java.util.Calendar.AUGUST:
case java.util.Calendar.SEPTEMBER:
quarter_name = "Q3";
quarter_number = "3";
year_quarter = year + "-" + quarter_name;
break;
case java.util.Calendar.OCTOBER:
case java.util.Calendar.NOVEMBER:
case java.util.Calendar.DECEMBER:
quarter_name = "Q4";
quarter_number = "4";
year_quarter = year + "-" + quarter_name;
break;
}
獲取JavaScript腳本中的變量
選擇記錄了 訪問國務院接口的網址字段 並選擇接收國務院返回的數據的變量名稱
使用JSON輸入組件進行接收 國務院返回的JSON數據
選擇獲取JSON中的字段 $.[0].info $.[0].info
匹配字段
給字段賦值
去除無用字段
輸出到 HDFS 集羣
剩下的就需要你按照業務字段的類型創建表了,在把data.parquet移動到對應的表分區目錄下,
最終修復一下表即可。這裏就不演示了。