zoukankan      html  css  js  c++  java
  • maxcompute根据起始时间,生成时间段多行日期数据

    具体需求是这样,有一张旅馆住宿表,表内有入住时间、离店时间等字段,现需要根据入住时间与离店时间生成入住期间的房晚数据。

    PS:实验环境为maxcompute,hive的同学请自行调整  (杂乱的命名请忽略= =)

    住宿测试表(test_get_dates):

    数据:

    需要生产的房晚数据:

    在大佬的鞭策下一共想了三种实现方案:

    1)mapjoin日期码表,使用不等值关联生成

    2)编写UDTF,传入开始与结束日期生成

    3)使用函数 LATERAL VIEW explode生成

    具体实现如下:

    (一)生成一张日期码表,并使用mapjoin的不等值关联

      1、创建时间码表dim_dates,如图

    (id可以省略)

     2、使用mapjoin关联码表生成所需数据

    select /*+MAPJOIN(a) */
    a.times,
    b.rzsj,
    b.tfsj,
    COALESCE(b.tfsj,b.rzsj) as bftfrq, --关联使用的住房日期
    b.sfzhm
    from dim_dates a
    join test_get_dates b
    on  a.times>=TO_DATE(to_char(b.rzsj,'yyyy-mm-dd'),'yyyy-mm-dd') and a.times<= TO_DATE(to_char(b.tfsj,'yyyy-mm-dd'),'yyyy-mm-dd')  

    查询结果如下

    (二)编写UDTF,返回多行日期数据

    1、编写UDTF,代码如下

    import com.aliyun.odps.udf.UDTF;
    import com.aliyun.odps.udf.annotation.Resolve;
    
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.GregorianCalendar;
    
    @Resolve({"datetime,datetime,string,string->datetime,string,string,datetime,datetime"})
    public class GetDatesUDTF extends UDTF {
        /**
         * @param args rzrq,tfrq,dwd_zjid,zjhm
         *             args[0] 入住日期
         *             args[1] 退房日期
         *             args[2] dwdid
         *             args[3] 身份证号码
         * @return 房晚日期,dwdid,身份证号码,入住时间,退房时间
         */
        @Override
        public void process(Object[] args) {
            Date bDate = (Date) args[0]; //获取入住时间
            Date eDate = (Date) args[1]; //获取退房时间
            Date bfDate = formateDate(bDate);
            Date efDate = formateDate(bDate!=null&&eDate==null?bDate:eDate);
            String dwdId = (String) args[2];
            String sfzhm = (String) args[3];
            if (bDate != null && efDate != null) {
                int days = getDateDiff(bfDate, efDate);
                try {
                    Date d;
                    for (int i = 0; i < days; i++) {
                        d = formateDate(getAddDate(bfDate,i));
                        forward(d, dwdId,sfzhm,bDate,eDate);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
        }
    
        public Date getAddDate(Date date,int days){
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(formateDate(date));
            calendar.add(Calendar.DAY_OF_MONTH, days);
            return calendar.getTime();
        }
    
        public Date formateDate(Date date) {
            if (date != null) {
                try {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String fdateStr = sdf.format(date);
                    date = sdf.parse(fdateStr);
                    return date;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
        public Date getEndDate(Date sdate, Date edate) {
            if (sdate != null && edate == null) {
               return formateDate(sdate);
            }
            return edate;
        }
    
        public int getDateDiff(Date sdate, Date edate) {
            long days = (edate.getTime() - sdate.getTime()) / (1000 * 60 * 60 * 24);
            return new Long(days).intValue();
        }
    }

    2、打包上传至maxcompute、创建函数getdates

    3、使用UDTF

     (三) 使用函数 LATERAL VIEW explode

    select tf.*,t.*, dateadd(start_date,pos,'dd')
    from (
    select 'a' as a, '2018-11-01 00:00:00' as start_date, '2018-12-01 00:00:00' as end_date from test_get_dates limit 1
    ) t
    lateral view posexplode(split(space(datediff(end_date,start_date,'dd')),' ')) tf as pos,val ;
  • 相关阅读:
    gdb调试libtool封装的可执行文件
    转载 Linux top命令详解
    VirtualBox使用物理硬盘建立磁盘
    【sqlServer】常用语句整理
    【c#基础】特殊集合
    【c# 基础】各种集合的不同情况下的性能
    【c#集合】Lookup 类 有序字典 SortedDictionary<TKey,TValue> 集
    【c#基础】集合--栈Stack 链表 LinkList 有序列表SortedList 字典Dictionary
    【c#基础】集合
    【c#基础】委托、Lambda表达式和事件
  • 原文地址:https://www.cnblogs.com/zzzmublog/p/11098710.html
Copyright © 2011-2022 走看看