join优化

join 优化(疑问1的效率为什么比2高:1用时115s,2用时170s)

一般来说join优化有三种方法1,mapjoin;2小表join大表;3join非驱动表添加索引

优化使用了mapjoin,小表join大表(给join表添加索引没有使用)

1

WITH
ins
                             AS (
  SELECT
  ins_id, ins_code, ins_name
  , TO_DATE(formal_time, 'yyyy/mm/dd') AS formal_time, ins_area_level
  , ins_emp_number_level, 1 AS flag, ins_emp_number
  FROM   dm_ins_info
  GROUP BY ins_id,
  ins_code,
  ins_name,
  formal_time,
  ins_area_level,
  ins_emp_number_level,
  ins_emp_number
),
t_marketing_metrics_book_rank
                             AS (
  SELECT ins.ins_id, ins.ins_code, ins.ins_name, tmmbrc.year, tmmbrc.period
  , CASE
  WHEN book.nums > 1000 THEN '教材等级S'
  WHEN book.nums > 500
  AND book.nums <= 1000 THEN '教材等级A'
  WHEN book.nums > 200
  AND book.nums <= 500 THEN '教材等级B'
  WHEN book.nums > 20
  AND book.nums <= 200 THEN '教材等级C'
  WHEN to_char(ins.formal_time, 'yyyymmdd') < tmmbrc.ins_formal_limiting_time
  AND COALESCE(book.nums, 0) <= 20 THEN '教材等级D'
  WHEN to_char(ins.formal_time, 'yyyymmdd') >= tmmbrc.ins_formal_limiting_time
  AND COALESCE(book.nums, 0) <= 20 THEN '教材等级X'
  ELSE '-'
  END AS book_rank, ins.ins_area_level, ins.ins_emp_number_level
  , COALESCE(book.nums, 0) AS book_nums, ins.ins_emp_number
  FROM
  -- (
  -- 	SELECT ins_id, ins_code, ins_name
  -- 		, TO_DATE(formal_time, 'yyyy/mm/dd') AS formal_time, ins_area_level
  -- 		, ins_emp_number_level, 1 AS flag, ins_emp_number
  -- 	FROM dm_ins_info
  -- 	GROUP BY ins_id,
  -- 		ins_code,
  -- 		ins_name,
  -- 		formal_time,
  -- 		ins_area_level,
  -- 		ins_emp_number_level,
  -- 		ins_emp_number
  -- )
  ins
    LEFT OUTER JOIN
    (
      SELECT year, period, ins_formal_limiting_time, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
    )
    tmmbrc
      ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT dtoi.ins_id, SUM(dtoi.num) AS nums, tmmbrc.year, tmmbrc.period
      FROM (
        SELECT *, 1 AS flag
        FROM dm_textbook_order
      ) dtoi
        LEFT OUTER JOIN
        (
          SELECT year, period, 1 AS flag
          FROM tmp_marketing_metrics_book_rank_config
          WHERE start_time <= '${bdp.system.bizdate}'
        )
        tmmbrc
          ON dtoi.flag = tmmbrc.flag
      WHERE dtoi.line = '主线'
      AND dtoi.status != '已取消'
      AND tmmbrc.period IN (dtoi.spring_season, dtoi.summer_season, dtoi.autumn_season, dtoi.winter_season)
      AND dtoi.goods_name NOT LIKE '%外研英语%'
      AND dtoi.textbook_order_year = tmmbrc.year
      GROUP BY dtoi.ins_id,
      tmmbrc.year,
      tmmbrc.period
    ) book
      ON ins.ins_id = book.ins_id
    AND tmmbrc.year = book.year
    AND tmmbrc.period = book.period
),

-------------------------------------------------------------------------------------------
-------临时表营销指标体系平均每周授课时长分类(tmp_marketing_metrics_sk_duration_week)------------
t_marketing_metrics_sk_duration_week
                             AS (
  SELECT ins.ins_id, tmmbrc.year, tmmbrc.period
  , CASE
  WHEN COALESCE(duration.avg_duration_hour, 0) < 1 THEN '平均老师周授课时长小于1小时'
  WHEN duration.avg_duration_hour >= 1
  AND duration.avg_duration_hour < 3 THEN '平均老师周授课时长1-3小时'
  WHEN duration.avg_duration_hour >= 3
  AND duration.avg_duration_hour < 5 THEN '平均老师周授课时长3-5小时'
  WHEN duration.avg_duration_hour >= 5
  AND duration.avg_duration_hour < 8 THEN '平均老师周授课时长5-8小时'
  WHEN duration.avg_duration_hour >= 8 THEN '平均老师周授课时长8小时以上'
  ELSE '-'
  END AS avg_duration_rank
  , round(COALESCE(duration.avg_duration_hour, 0), 2) AS avg_duration_hour
  , round(COALESCE(duration.avg_duration_minute, 0), 0) AS avg_duration_minute
  FROM
  -- (
  -- 	SELECT ins_id, 1 AS flag
  -- 	FROM dm_ins_info
  -- 	GROUP BY ins_id
  -- )
  ins
    LEFT OUTER JOIN
    (
      SELECT year, period, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
      AND start_time >= '20170901'
    )
    tmmbrc
      ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT ins_id, year, period
      , SUM(duration_hour) / COUNT(1) AS avg_duration_hour, SUM(duration_minute) / COUNT(1) AS avg_duration_minute
      FROM (
        SELECT  /*+ mapjoin(tmmbrc) */
        dbd.ins_id, dbd.user_id, dbd.user_phone, dbd.user_name, dbd.week_of_year
        , tmmbrc.year, tmmbrc.period, SUM(duration) / 3600 AS duration_hour, SUM(duration) / 60 as duration_minute
        FROM (
              select * from dm_beishouke_duration
              WHERE page_type = '授课'
              AND cooperate_code IN ('合作中', '合作结束')
              AND institution_type = '正式'
            )
            dbd
          LEFT OUTER JOIN tmp_marketing_metrics_book_rank_config tmmbrc
            ON CAST(dbd.year AS BIGINT) = tmmbrc.year
          AND dbd.day >= tmmbrc.start_time
          AND dbd.day < tmmbrc.end_time
        GROUP BY dbd.ins_id,
        dbd.user_id,
        dbd.user_phone,
        dbd.user_name,
        dbd.week_of_year,
        tmmbrc.year,
        tmmbrc.period
      ) tmp1
      GROUP BY ins_id,
      year,
      period
    ) duration
      ON ins.ins_id = duration.ins_id
    AND tmmbrc.year = duration.year
    AND tmmbrc.period = duration.period
),
-------------------------------------------------------------------------------------
----------临时表营销指标体系--健康度(tmp_marketing_metrics_health_degree)--------------
tmp_book_info AS (
  SELECT dtoi.ins_id, SUM(dtoi.num) AS nums, tmmbrc.year, tmmbrc.period
  , dtoi.subject_name
  FROM (
    SELECT *, 1 AS flag
    FROM dm_textbook_order
    WHERE line = '主线'
    AND status != '已取消'
    AND goods_name NOT LIKE '%外研英语%'
  ) dtoi
    LEFT OUTER JOIN
    (
      SELECT year, period, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
    )
    tmmbrc
      ON dtoi.flag = tmmbrc.flag
  WHERE tmmbrc.period IN (dtoi.spring_season, dtoi.summer_season, dtoi.autumn_season, dtoi.winter_season)
  AND dtoi.textbook_order_year = tmmbrc.year
  GROUP BY dtoi.ins_id,
  tmmbrc.year,
  tmmbrc.period,
  dtoi.subject_name
),

t_marketing_metrics_health_degree
                             AS (
  SELECT ins.ins_id, tmmbrc.year, tmmbrc.period
  , CASE
  WHEN effect.sp_nums = 1 THEN '购买正式学科数为1'
  WHEN total.total_nums <= 20
  OR total.total_nums IS NULL
  OR effect.sp_nums IS NULL THEN '购买正式学科数为0'
  ELSE concat(round((1 - max.max_nums / effect.total_nums) * 100, 1), '%')
  END AS expand_rate
  , CASE
  WHEN ins.ins_emp_number = 0 THEN '机构规模为0'
  WHEN total.total_nums IS NULL THEN '该学期教材为0'
  ELSE concat(round((total.total_nums / ins.ins_emp_number) * 100, 1) , '%')
  END AS permeate_rate
  , CASE
  WHEN last.last_nums IS NULL THEN '对比学期教材为0'
  WHEN total.total_nums IS NULL THEN '-100%'
  ELSE concat(round((total.total_nums / last.last_nums - 1) * 100, 1) , '%')
  END AS incre_rate
  FROM
  -- (
  -- 	SELECT ins_id, ins_emp_number, 1 AS flag
  -- 	FROM dm_ins_info
  -- 	GROUP BY ins_id,
  -- 		ins_emp_number
  -- )
  ins
    LEFT OUTER JOIN
    (
      SELECT *, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
    )
    tmmbrc
      ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT ins_id, year, period, SUM(nums) AS total_nums
      , COUNT(1) AS sp_nums
      FROM tmp_book_info
      WHERE nums > 20
      GROUP BY ins_id,
      year,
      period
    ) effect
      ON ins.ins_id = effect.ins_id
    AND tmmbrc.year = effect.year
    AND tmmbrc.period = effect.period
    LEFT OUTER JOIN (
      SELECT ins_id, year, period, SUM(nums) AS total_nums
      FROM tmp_book_info
      GROUP BY ins_id,
      year,
      period
    ) total
      ON ins.ins_id = total.ins_id
    AND tmmbrc.year = total.year
    AND tmmbrc.period = total.period
    LEFT OUTER JOIN (
      SELECT ins_id, year, period, SUM(nums) AS last_nums
      FROM tmp_book_info
      GROUP BY ins_id,
      year,
      period
    ) last
      ON ins.ins_id = last.ins_id
    AND last.year = tmmbrc.last_year
    AND last.period = tmmbrc.last_period
    LEFT OUTER JOIN (
      SELECT ins_id, year, period, MAX(nums) AS max_nums
      FROM tmp_book_info
      WHERE nums > 20
      GROUP BY ins_id,
      year,
      period
    ) max
      ON ins.ins_id = max.ins_id
    AND max.year = tmmbrc.year
    AND max.period = tmmbrc.period
)  ,
-------------------------------------------------------------------------------------------
-----------临时表营销指标体系--服务度--师训服务(tmp_marketing_metrics_service_degree_tt)----
tmp_marketing_metrics_tt_nums
                             as (
-- 获取机构每学期参加师训教师人数
  SELECT /*+ mapjoin(tmmbrc) */
  tmmbrc.year, tmmbrc.period, tmp1.ins_id,
  COUNT(DISTINCT user_id) AS nums
  FROM (
    SELECT user_id, ins_id
    , CASE
           WHEN course_type = '现场' THEN course_start_time
           WHEN course_type = '点播' THEN apply_time
           WHEN course_type = '直播'
    AND course_start_time <= apply_time THEN apply_time
           WHEN course_type = '直播'
    AND course_start_time > apply_time THEN course_start_time
           ELSE NULL
           END AS join_time
    FROM dm_train_course_user
    WHERE apply_status_desc IN ('已报名成功', '后台补报')
    AND institution_type = '正式'
    AND ins_cooperate_state = '合作中'
  ) tmp1
    LEFT OUTER JOIN tmp_marketing_metrics_book_rank_config tmmbrc
      ON TO_CHAR(join_time, 'yyyymmdd') >= tmmbrc.start_time
    AND TO_CHAR(join_time, 'yyyymmdd') < tmmbrc.end_time
  GROUP BY tmmbrc.year,
  tmmbrc.period,
  tmp1.ins_id
),
t_marketing_metrics_acc_nums AS (
--机构老师账号数量统计
  SELECT /*+ mapjoin(tmmbrc) */
  tmmbrc.year, tmmbrc.period, daa.institution_id,
  COUNT(DISTINCT teacher_id) AS nums
  FROM dm_account_all daa
    LEFT OUTER JOIN tmp_marketing_metrics_book_rank_config tmmbrc
      ON to_char(daa.end_time, 'yyyymmdd') >= tmmbrc.start_time
    AND to_char(daa.start_time, 'yyyymmdd') < tmmbrc.end_time
  WHERE daa.statistical_status = 1
  GROUP BY daa.institution_id,
  tmmbrc.year,
  tmmbrc.period
),
t_marketing_metrics_service_degree_tt
                             AS
(
  SELECT ins.ins_id, tmmbrc.year, tmmbrc.period
  , CASE
  WHEN tmmtn.nums / tmman.nums < 0.5 THEN '一星服务'
  WHEN tmmtn.nums / tmman.nums >= 0.5
  AND tmmtn.nums / tmman.nums < 1 THEN '二星服务'
  WHEN tmmtn.nums / tmman.nums >= 1
  AND tmmtn.nums / tmman.nums < 1.5 THEN '三星服务'
  WHEN tmmtn.nums / tmman.nums >= 1.5
  AND tmmtn.nums / tmman.nums < 2 THEN '四星服务'
  WHEN tmmtn.nums / tmman.nums >= 2 THEN '五星服务'
  WHEN tmmtn.nums IS NULL AND tmman.nums IS not NULL THEN '未参加师训'
  WHEN tmman.nums IS NULL AND  tmmtn.nums IS NOT NULL THEN '无教师账号'
  WHEN tmman.nums IS NULL AND tmmtn.nums IS NULL THEN '无账号未师训'
  ELSE '-'
  END AS tt_rank
  FROM
  -- (
  --     SELECT ins_id, 1 AS flag
  --     FROM dm_ins_info
  --     GROUP BY ins_id
  -- )
  ins
    LEFT OUTER JOIN
    (
      SELECT year, period, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
    )
    tmmbrc
      ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN tmp_marketing_metrics_tt_nums tmmtn
      ON ins.ins_id = tmmtn.ins_id
    AND tmmbrc.year = tmmtn.year
    AND tmmbrc.period = tmmtn.period
    LEFT OUTER JOIN t_marketing_metrics_acc_nums tmman
      ON ins.ins_id = tmman.institution_id
    AND tmmbrc.year = tmman.year
    AND tmmbrc.period = tmman.period
),
--------------------------------------------------------------------------------------------
-----临时表营销指标体系--AS服务度机构数量分布及占比(tmp_marketing_metrics_service_degree_as)----
t_marketing_metrics_service_degree_as
AS (
  SELECT /*+ mapjoin(ins,tmmbrc) */
  ins.ins_id, tmmbrc.year, tmmbrc.period,
  CASE
  WHEN as_user.nums IS NULL AND book.nums IS NULL THEN '未使用AS及教材'
  WHEN as_user.nums IS NULL AND book.nums IS NOT NULL THEN '未使用AS'
  WHEN book.nums IS NULL AND as_user.nums IS NOT NULL THEN '未使用教材'
  WHEN as_user.nums / book.nums < 0.5 THEN '一星服务'
  WHEN as_user.nums / book.nums >= 0.5
  AND as_user.nums / book.nums < 1 THEN '二星服务'
  WHEN as_user.nums / book.nums >= 1
  AND as_user.nums / book.nums < 1.5 THEN '三星服务'
  WHEN as_user.nums / book.nums >= 1.5
  AND as_user.nums / book.nums < 2 THEN '四星服务'
  WHEN as_user.nums / book.nums >= 2 THEN '五星服务'
  ELSE '-'
  END AS as_rank
  FROM
  -- (
  --     SELECT ins_id, 1 AS flag
  --     FROM dm_ins_info
  --     GROUP BY ins_id
  -- )
  ins
  LEFT OUTER JOIN
  (
    SELECT year, period, 1 AS flag
    FROM tmp_marketing_metrics_book_rank_config
    WHERE start_time <= '${bdp.system.bizdate}'
  )
  tmmbrc
    ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT dtoi.ins_id, SUM(dtoi.num) AS nums, tmmbrc.year, tmmbrc.period
      FROM
      (
          SELECT year, period, 1 AS flag
          FROM tmp_marketing_metrics_book_rank_config
          WHERE start_time <= '${bdp.system.bizdate}'
        )
        tmmbrc
        LEFT OUTER JOIN
        (
          SELECT *, 1 AS flag
          FROM dm_textbook_order
          WHERE line = '主线'
          AND status != '已取消'
          AND goods_name NOT LIKE '%外研英语%'
        ) dtoi
          ON dtoi.flag = tmmbrc.flag
      WHERE tmmbrc.period IN (dtoi.spring_season, dtoi.summer_season, dtoi.autumn_season, dtoi.winter_season)
      AND dtoi.textbook_order_year = tmmbrc.year
      GROUP BY dtoi.ins_id,
      tmmbrc.year,
      tmmbrc.period
    ) book
      ON ins.ins_id = book.ins_id
    AND tmmbrc.year = book.year
    AND tmmbrc.period = book.period
    LEFT OUTER JOIN (
          SELECT /*+ mapjoin(tmmbrc) */
          tmmbrc.year, tmmbrc.period, dshin.institution_id,
          COUNT(DISTINCT dshin.student_id) AS nums
          FROM(
            select institution_id,student_id,period_name,time
            from dm_student_homework_info_new
            where day = '${bdp.system.bizdate}'
              ) dshin
          LEFT OUTER JOIN
           (
            select * from
            tmp_marketing_metrics_book_rank_config
            where period IS NOT NULL
            ) tmmbrc
          ON SUBSTR(tmmbrc.period, 1, 1) = dshin.period_name
              AND to_char(time, 'yyyymmdd') >= tmmbrc.start_time
              AND to_char(time, 'yyyymmdd') < tmmbrc.end_time
          --      WHERE dshin.day = '${bdp.system.bizdate}' AND tmmbrc.period IS NOT NULL
          GROUP BY tmmbrc.year,
          tmmbrc.period,
          dshin.institution_id
    ) as_user
      ON ins.ins_id = as_user.institution_id
        AND tmmbrc.year = as_user.year
        AND tmmbrc.period = as_user.period
),
--------------------------------------------------------------------------------------------
--临时表营销指标体系--答题器服务度机构数量分布及占比(tmp_marketing_metrics_service_degree_i_clicker)
t_marketing_metrics_service_degree_i_clicker
                             AS (
  SELECT /*+ mapjoin(ins,tmmbrc) */
  ins.ins_id, tmmbrc.year, tmmbrc.period,
  CASE
  WHEN i_clicker.nums IS NULL AND book.nums IS NULL THEN '未使用答题器及教材'
  WHEN i_clicker.nums IS NULL AND book.nums IS NOT NULL THEN '未使用答题器'
  WHEN book.nums IS NULL AND i_clicker.nums IS NOT NULL THEN '未使用教材'
  WHEN i_clicker.nums / book.nums < 0.5 THEN '一星服务'
  WHEN i_clicker.nums / book.nums >= 0.5
  AND i_clicker.nums / book.nums < 1 THEN '二星服务'
  WHEN i_clicker.nums / book.nums >= 1
  AND i_clicker.nums / book.nums < 1.5 THEN '三星服务'
  WHEN i_clicker.nums / book.nums >= 1.5
  AND i_clicker.nums / book.nums < 2 THEN '四星服务'
  WHEN i_clicker.nums / book.nums >= 2 THEN '五星服务'
  ELSE '-'
  END AS i_clicker_rank
  FROM
  --  (
  --     SELECT ins_id, 1 AS flag
  --     FROM dm_ins_info
  --     GROUP BY ins_id
  -- )
  ins
  LEFT OUTER JOIN
    (
      SELECT year, period, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
    )
  tmmbrc
  ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT /*+ mapjoin(tmmbrc)*/
      dtoi.ins_id, SUM(dtoi.num) AS nums, tmmbrc.year, tmmbrc.period
      FROM (
        SELECT year, period, 1 AS flag
        FROM tmp_marketing_metrics_book_rank_config
        WHERE start_time <= '${bdp.system.bizdate}'
      )
      tmmbrc
      LEFT OUTER JOIN
      (
        SELECT *, 1 AS flag
        FROM dm_textbook_order
        WHERE line = '主线'
        AND status != '已取消'
        AND goods_name NOT LIKE '%外研英语%'
        ) dtoi
          ON dtoi.flag = tmmbrc.flag
      WHERE tmmbrc.period IN (dtoi.spring_season, dtoi.summer_season, dtoi.autumn_season, dtoi.winter_season)
      AND dtoi.textbook_order_year = tmmbrc.year
      GROUP BY dtoi.ins_id,
      tmmbrc.year,
      tmmbrc.period
    ) book
      ON ins.ins_id = book.ins_id
    AND tmmbrc.year = book.year
    AND tmmbrc.period = book.period
  LEFT OUTER JOIN(
    SELECT /*+ mapjoin(tmmbrc) */
    tmmbrc.year, tmmbrc.period, ddsa.ins_id,
    COUNT(DISTINCT ddsa.student_id) AS nums
    FROM  (
      select * from tmp_marketing_metrics_book_rank_config
      where  period IS NOT NULL
    ) tmmbrc
    LEFT OUTER JOIN dm_dt_schedule_answer ddsa
      ON SUBSTR(tmmbrc.period, 1, 1) = ddsa.period
        AND to_char(ddsa.start_time, 'yyyymmdd') >= tmmbrc.start_time
        AND to_char(ddsa.start_time, 'yyyymmdd') < tmmbrc.end_time
    GROUP BY tmmbrc.year,
    tmmbrc.period,
    ddsa.ins_id,
    ddsa.period
  ) i_clicker
    ON ins.ins_id = i_clicker.ins_id
      AND tmmbrc.year = i_clicker.year
      AND tmmbrc.period = i_clicker.period
)
--------------------------------------营销指标体系-------------------------------------------
INSERT OVERWRITE TABLE bi_marketing_metrics_ins_info
  SELECT
  book.ins_id, book.ins_code, book.ins_name, book.year, book.period
  , book.book_rank, book.ins_area_level, book.ins_emp_number_level
  , COALESCE(sk_duration.avg_duration_rank, '-'), health.expand_rate
  , health.permeate_rate, health.incre_rate, tt.tt_rank, asd.as_rank, i_clicker.i_clicker_rank
  , book.book_nums, cast(book.ins_emp_number as bigint) as ins_emp_number, COALESCE(sk_duration.avg_duration_hour, 0) AS avg_duration_hour
  ,cast(COALESCE(sk_duration.avg_duration_minute, 0) as bigint)AS avg_duration_minute
  FROM t_marketing_metrics_book_rank book
  LEFT OUTER JOIN t_marketing_metrics_sk_duration_week sk_duration
    ON book.ins_id = sk_duration.ins_id
      AND book.year = sk_duration.year
      AND book.period = sk_duration.period
  LEFT OUTER JOIN t_marketing_metrics_health_degree health
    ON book.ins_id = health.ins_id
      AND book.year = health.year
      AND book.period = health.period
  LEFT OUTER JOIN t_marketing_metrics_service_degree_tt tt
    ON book.ins_id = tt.ins_id
      AND book.year = tt.year
      AND book.period = tt.period
  LEFT OUTER JOIN t_marketing_metrics_service_degree_as asd
    ON book.ins_id = asd.ins_id
      AND book.year = asd.year
      AND book.period = asd.period
  LEFT OUTER JOIN t_marketing_metrics_service_degree_i_clicker i_clicker
    ON book.ins_id = i_clicker.ins_id
      AND book.year = i_clicker.year
      AND book.period = i_clicker.period;




2

WITH
ins
                             AS (
  SELECT
  ins_id, ins_code, ins_name
  , TO_DATE(formal_time, 'yyyy/mm/dd') AS formal_time, ins_area_level
  , ins_emp_number_level, 1 AS flag, ins_emp_number
  FROM   dm_ins_info
  GROUP BY ins_id,
  ins_code,
  ins_name,
  formal_time,
  ins_area_level,
  ins_emp_number_level,
  ins_emp_number
),
t_marketing_metrics_book_rank
                             AS (
  SELECT ins.ins_id, ins.ins_code, ins.ins_name, tmmbrc.year, tmmbrc.period
  , CASE
  WHEN book.nums > 1000 THEN '教材等级S'
  WHEN book.nums > 500
  AND book.nums <= 1000 THEN '教材等级A'
  WHEN book.nums > 200
  AND book.nums <= 500 THEN '教材等级B'
  WHEN book.nums > 20
  AND book.nums <= 200 THEN '教材等级C'
  WHEN to_char(ins.formal_time, 'yyyymmdd') < tmmbrc.ins_formal_limiting_time
  AND COALESCE(book.nums, 0) <= 20 THEN '教材等级D'
  WHEN to_char(ins.formal_time, 'yyyymmdd') >= tmmbrc.ins_formal_limiting_time
  AND COALESCE(book.nums, 0) <= 20 THEN '教材等级X'
  ELSE '-'
  END AS book_rank, ins.ins_area_level, ins.ins_emp_number_level
  , COALESCE(book.nums, 0) AS book_nums, ins.ins_emp_number
  FROM
  -- (
  -- 	SELECT ins_id, ins_code, ins_name
  -- 		, TO_DATE(formal_time, 'yyyy/mm/dd') AS formal_time, ins_area_level
  -- 		, ins_emp_number_level, 1 AS flag, ins_emp_number
  -- 	FROM dm_ins_info
  -- 	GROUP BY ins_id,
  -- 		ins_code,
  -- 		ins_name,
  -- 		formal_time,
  -- 		ins_area_level,
  -- 		ins_emp_number_level,
  -- 		ins_emp_number
  -- )
  ins
    LEFT OUTER JOIN
    (
      SELECT year, period, ins_formal_limiting_time, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
    )
    tmmbrc
      ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT dtoi.ins_id, SUM(dtoi.num) AS nums, tmmbrc.year, tmmbrc.period
      FROM (
        SELECT *, 1 AS flag
        FROM dm_textbook_order
      ) dtoi
        LEFT OUTER JOIN
        (
          SELECT year, period, 1 AS flag
          FROM tmp_marketing_metrics_book_rank_config
          WHERE start_time <= '${bdp.system.bizdate}'
        )
        tmmbrc
          ON dtoi.flag = tmmbrc.flag
      WHERE dtoi.line = '主线'
      AND dtoi.status != '已取消'
      AND tmmbrc.period IN (dtoi.spring_season, dtoi.summer_season, dtoi.autumn_season, dtoi.winter_season)
      AND dtoi.goods_name NOT LIKE '%外研英语%'
      AND dtoi.textbook_order_year = tmmbrc.year
      GROUP BY dtoi.ins_id,
      tmmbrc.year,
      tmmbrc.period
    ) book
      ON ins.ins_id = book.ins_id
    AND tmmbrc.year = book.year
    AND tmmbrc.period = book.period
),

-------------------------------------------------------------------------------------------
-------临时表营销指标体系平均每周授课时长分类(tmp_marketing_metrics_sk_duration_week)------------
t_marketing_metrics_sk_duration_week
                             AS (
  SELECT ins.ins_id, tmmbrc.year, tmmbrc.period
  , CASE
  WHEN COALESCE(duration.avg_duration_hour, 0) < 1 THEN '平均老师周授课时长小于1小时'
  WHEN duration.avg_duration_hour >= 1
  AND duration.avg_duration_hour < 3 THEN '平均老师周授课时长1-3小时'
  WHEN duration.avg_duration_hour >= 3
  AND duration.avg_duration_hour < 5 THEN '平均老师周授课时长3-5小时'
  WHEN duration.avg_duration_hour >= 5
  AND duration.avg_duration_hour < 8 THEN '平均老师周授课时长5-8小时'
  WHEN duration.avg_duration_hour >= 8 THEN '平均老师周授课时长8小时以上'
  ELSE '-'
  END AS avg_duration_rank
  , round(COALESCE(duration.avg_duration_hour, 0), 2) AS avg_duration_hour
  , round(COALESCE(duration.avg_duration_minute, 0), 0) AS avg_duration_minute
  FROM
  -- (
  -- 	SELECT ins_id, 1 AS flag
  -- 	FROM dm_ins_info
  -- 	GROUP BY ins_id
  -- )
  ins
    LEFT OUTER JOIN
    (
      SELECT year, period, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
      AND start_time >= '20170901'
    )
    tmmbrc
      ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT ins_id, year, period
      , SUM(duration_hour) / COUNT(1) AS avg_duration_hour, SUM(duration_minute) / COUNT(1) AS avg_duration_minute
      FROM (
        SELECT  /*+ mapjoin(tmmbrc) */
        dbd.ins_id, dbd.user_id, dbd.user_phone, dbd.user_name, dbd.week_of_year
        , tmmbrc.year, tmmbrc.period, SUM(duration) / 3600 AS duration_hour, SUM(duration) / 60 as duration_minute
        FROM (
              select * from dm_beishouke_duration
              WHERE page_type = '授课'
              AND cooperate_code IN ('合作中', '合作结束')
              AND institution_type = '正式'
            )
            dbd
          LEFT OUTER JOIN tmp_marketing_metrics_book_rank_config tmmbrc
            ON CAST(dbd.year AS BIGINT) = tmmbrc.year
          AND dbd.day >= tmmbrc.start_time
          AND dbd.day < tmmbrc.end_time
        GROUP BY dbd.ins_id,
        dbd.user_id,
        dbd.user_phone,
        dbd.user_name,
        dbd.week_of_year,
        tmmbrc.year,
        tmmbrc.period
      ) tmp1
      GROUP BY ins_id,
      year,
      period
    ) duration
      ON ins.ins_id = duration.ins_id
    AND tmmbrc.year = duration.year
    AND tmmbrc.period = duration.period
),
-------------------------------------------------------------------------------------
----------临时表营销指标体系--健康度(tmp_marketing_metrics_health_degree)--------------
tmp_book_info AS (
  SELECT dtoi.ins_id, SUM(dtoi.num) AS nums, tmmbrc.year, tmmbrc.period
  , dtoi.subject_name
  FROM (
    SELECT *, 1 AS flag
    FROM dm_textbook_order
    WHERE line = '主线'
    AND status != '已取消'
    AND goods_name NOT LIKE '%外研英语%'
  ) dtoi
    LEFT OUTER JOIN
    (
      SELECT year, period, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
    )
    tmmbrc
      ON dtoi.flag = tmmbrc.flag
  WHERE tmmbrc.period IN (dtoi.spring_season, dtoi.summer_season, dtoi.autumn_season, dtoi.winter_season)
  AND dtoi.textbook_order_year = tmmbrc.year
  GROUP BY dtoi.ins_id,
  tmmbrc.year,
  tmmbrc.period,
  dtoi.subject_name
),

t_marketing_metrics_health_degree
                             AS (
  SELECT ins.ins_id, tmmbrc.year, tmmbrc.period
  , CASE
  WHEN effect.sp_nums = 1 THEN '购买正式学科数为1'
  WHEN total.total_nums <= 20
  OR total.total_nums IS NULL
  OR effect.sp_nums IS NULL THEN '购买正式学科数为0'
  ELSE concat(round((1 - max.max_nums / effect.total_nums) * 100, 1), '%')
  END AS expand_rate
  , CASE
  WHEN ins.ins_emp_number = 0 THEN '机构规模为0'
  WHEN total.total_nums IS NULL THEN '该学期教材为0'
  ELSE concat(round((total.total_nums / ins.ins_emp_number) * 100, 1) , '%')
  END AS permeate_rate
  , CASE
  WHEN last.last_nums IS NULL THEN '对比学期教材为0'
  WHEN total.total_nums IS NULL THEN '-100%'
  ELSE concat(round((total.total_nums / last.last_nums - 1) * 100, 1) , '%')
  END AS incre_rate
  FROM
  -- (
  -- 	SELECT ins_id, ins_emp_number, 1 AS flag
  -- 	FROM dm_ins_info
  -- 	GROUP BY ins_id,
  -- 		ins_emp_number
  -- )
  ins
    LEFT OUTER JOIN
    (
      SELECT *, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
    )
    tmmbrc
      ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT ins_id, year, period, SUM(nums) AS total_nums
      , COUNT(1) AS sp_nums
      FROM tmp_book_info
      WHERE nums > 20
      GROUP BY ins_id,
      year,
      period
    ) effect
      ON ins.ins_id = effect.ins_id
    AND tmmbrc.year = effect.year
    AND tmmbrc.period = effect.period
    LEFT OUTER JOIN (
      SELECT ins_id, year, period, SUM(nums) AS total_nums
      FROM tmp_book_info
      GROUP BY ins_id,
      year,
      period
    ) total
      ON ins.ins_id = total.ins_id
    AND tmmbrc.year = total.year
    AND tmmbrc.period = total.period
    LEFT OUTER JOIN (
      SELECT ins_id, year, period, SUM(nums) AS last_nums
      FROM tmp_book_info
      GROUP BY ins_id,
      year,
      period
    ) last
      ON ins.ins_id = last.ins_id
    AND last.year = tmmbrc.last_year
    AND last.period = tmmbrc.last_period
    LEFT OUTER JOIN (
      SELECT ins_id, year, period, MAX(nums) AS max_nums
      FROM tmp_book_info
      WHERE nums > 20
      GROUP BY ins_id,
      year,
      period
    ) max
      ON ins.ins_id = max.ins_id
    AND max.year = tmmbrc.year
    AND max.period = tmmbrc.period
)  ,
-------------------------------------------------------------------------------------------
-----------临时表营销指标体系--服务度--师训服务(tmp_marketing_metrics_service_degree_tt)----
tmp_marketing_metrics_tt_nums
                             as (
-- 获取机构每学期参加师训教师人数
  SELECT /*+ mapjoin(tmmbrc) */
  tmmbrc.year, tmmbrc.period, tmp1.ins_id,
  COUNT(DISTINCT user_id) AS nums
  FROM (
    SELECT user_id, ins_id
    , CASE
           WHEN course_type = '现场' THEN course_start_time
           WHEN course_type = '点播' THEN apply_time
           WHEN course_type = '直播'
    AND course_start_time <= apply_time THEN apply_time
           WHEN course_type = '直播'
    AND course_start_time > apply_time THEN course_start_time
           ELSE NULL
           END AS join_time
    FROM dm_train_course_user
    WHERE apply_status_desc IN ('已报名成功', '后台补报')
    AND institution_type = '正式'
    AND ins_cooperate_state = '合作中'
  ) tmp1
    LEFT OUTER JOIN tmp_marketing_metrics_book_rank_config tmmbrc
      ON TO_CHAR(join_time, 'yyyymmdd') >= tmmbrc.start_time
    AND TO_CHAR(join_time, 'yyyymmdd') < tmmbrc.end_time
  GROUP BY tmmbrc.year,
  tmmbrc.period,
  tmp1.ins_id
),
t_marketing_metrics_acc_nums AS (
--机构老师账号数量统计
  SELECT /*+ mapjoin(tmmbrc) */
  tmmbrc.year, tmmbrc.period, daa.institution_id,
  COUNT(DISTINCT teacher_id) AS nums
  FROM dm_account_all daa
    LEFT OUTER JOIN tmp_marketing_metrics_book_rank_config tmmbrc
      ON to_char(daa.end_time, 'yyyymmdd') >= tmmbrc.start_time
    AND to_char(daa.start_time, 'yyyymmdd') < tmmbrc.end_time
  WHERE daa.statistical_status = 1
  GROUP BY daa.institution_id,
  tmmbrc.year,
  tmmbrc.period
),
t_marketing_metrics_service_degree_tt
                             AS
(
  SELECT ins.ins_id, tmmbrc.year, tmmbrc.period
  , CASE
  WHEN tmmtn.nums / tmman.nums < 0.5 THEN '一星服务'
  WHEN tmmtn.nums / tmman.nums >= 0.5
  AND tmmtn.nums / tmman.nums < 1 THEN '二星服务'
  WHEN tmmtn.nums / tmman.nums >= 1
  AND tmmtn.nums / tmman.nums < 1.5 THEN '三星服务'
  WHEN tmmtn.nums / tmman.nums >= 1.5
  AND tmmtn.nums / tmman.nums < 2 THEN '四星服务'
  WHEN tmmtn.nums / tmman.nums >= 2 THEN '五星服务'
  WHEN tmmtn.nums IS NULL AND tmman.nums IS not NULL THEN '未参加师训'
  WHEN tmman.nums IS NULL AND  tmmtn.nums IS NOT NULL THEN '无教师账号'
  WHEN tmman.nums IS NULL AND tmmtn.nums IS NULL THEN '无账号未师训'
  ELSE '-'
  END AS tt_rank
  FROM
  -- (
  --     SELECT ins_id, 1 AS flag
  --     FROM dm_ins_info
  --     GROUP BY ins_id
  -- )
  ins
    LEFT OUTER JOIN
    (
      SELECT year, period, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
    )
    tmmbrc
      ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN tmp_marketing_metrics_tt_nums tmmtn
      ON ins.ins_id = tmmtn.ins_id
    AND tmmbrc.year = tmmtn.year
    AND tmmbrc.period = tmmtn.period
    LEFT OUTER JOIN t_marketing_metrics_acc_nums tmman
      ON ins.ins_id = tmman.institution_id
    AND tmmbrc.year = tmman.year
    AND tmmbrc.period = tmman.period
),
--------------------------------------------------------------------------------------------
-----临时表营销指标体系--AS服务度机构数量分布及占比(tmp_marketing_metrics_service_degree_as)----
t_marketing_metrics_service_degree_as
AS (
  SELECT /*+ mapjoin(ins,tmmbrc) */
  ins.ins_id, tmmbrc.year, tmmbrc.period,
  CASE
  WHEN as_user.nums IS NULL AND book.nums IS NULL THEN '未使用AS及教材'
  WHEN as_user.nums IS NULL AND book.nums IS NOT NULL THEN '未使用AS'
  WHEN book.nums IS NULL AND as_user.nums IS NOT NULL THEN '未使用教材'
  WHEN as_user.nums / book.nums < 0.5 THEN '一星服务'
  WHEN as_user.nums / book.nums >= 0.5
  AND as_user.nums / book.nums < 1 THEN '二星服务'
  WHEN as_user.nums / book.nums >= 1
  AND as_user.nums / book.nums < 1.5 THEN '三星服务'
  WHEN as_user.nums / book.nums >= 1.5
  AND as_user.nums / book.nums < 2 THEN '四星服务'
  WHEN as_user.nums / book.nums >= 2 THEN '五星服务'
  ELSE '-'
  END AS as_rank
  FROM
  -- (
  --     SELECT ins_id, 1 AS flag
  --     FROM dm_ins_info
  --     GROUP BY ins_id
  -- )
  ins
  LEFT OUTER JOIN
  (
    SELECT year, period, 1 AS flag
    FROM tmp_marketing_metrics_book_rank_config
    WHERE start_time <= '${bdp.system.bizdate}'
  )
  tmmbrc
    ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT dtoi.ins_id, SUM(dtoi.num) AS nums, tmmbrc.year, tmmbrc.period
      FROM
      (
          SELECT year, period, 1 AS flag
          FROM tmp_marketing_metrics_book_rank_config
          WHERE start_time <= '${bdp.system.bizdate}'
        )
        tmmbrc
        LEFT OUTER JOIN
        (
          SELECT *, 1 AS flag
          FROM dm_textbook_order
          WHERE line = '主线'
          AND status != '已取消'
          AND goods_name NOT LIKE '%外研英语%'
        ) dtoi
          ON dtoi.flag = tmmbrc.flag
      WHERE tmmbrc.period IN (dtoi.spring_season, dtoi.summer_season, dtoi.autumn_season, dtoi.winter_season)
      AND dtoi.textbook_order_year = tmmbrc.year
      GROUP BY dtoi.ins_id,
      tmmbrc.year,
      tmmbrc.period
    ) book
      ON ins.ins_id = book.ins_id
    AND tmmbrc.year = book.year
    AND tmmbrc.period = book.period
    LEFT OUTER JOIN (
          SELECT /*+ mapjoin(tmmbrc) */
          tmmbrc.year, tmmbrc.period, dshin.institution_id,
          COUNT(DISTINCT dshin.student_id) AS nums
          FROM(
            select institution_id,student_id,period_name,time
            from dm_student_homework_info_new
            where day = '${bdp.system.bizdate}'
              ) dshin
          LEFT OUTER JOIN
           (
            select * from
            tmp_marketing_metrics_book_rank_config
            where period IS NOT NULL
            ) tmmbrc
          ON SUBSTR(tmmbrc.period, 1, 1) = dshin.period_name
              AND to_char(time, 'yyyymmdd') >= tmmbrc.start_time
              AND to_char(time, 'yyyymmdd') < tmmbrc.end_time
          --      WHERE dshin.day = '${bdp.system.bizdate}' AND tmmbrc.period IS NOT NULL
          GROUP BY tmmbrc.year,
          tmmbrc.period,
          dshin.institution_id
    ) as_user
      ON ins.ins_id = as_user.institution_id
        AND tmmbrc.year = as_user.year
        AND tmmbrc.period = as_user.period
),
--------------------------------------------------------------------------------------------
--临时表营销指标体系--答题器服务度机构数量分布及占比(tmp_marketing_metrics_service_degree_i_clicker)
t_marketing_metrics_service_degree_i_clicker
                             AS (
  SELECT /*+ mapjoin(ins,tmmbrc) */
  ins.ins_id, tmmbrc.year, tmmbrc.period,
  CASE
  WHEN i_clicker.nums IS NULL AND book.nums IS NULL THEN '未使用答题器及教材'
  WHEN i_clicker.nums IS NULL AND book.nums IS NOT NULL THEN '未使用答题器'
  WHEN book.nums IS NULL AND i_clicker.nums IS NOT NULL THEN '未使用教材'
  WHEN i_clicker.nums / book.nums < 0.5 THEN '一星服务'
  WHEN i_clicker.nums / book.nums >= 0.5
  AND i_clicker.nums / book.nums < 1 THEN '二星服务'
  WHEN i_clicker.nums / book.nums >= 1
  AND i_clicker.nums / book.nums < 1.5 THEN '三星服务'
  WHEN i_clicker.nums / book.nums >= 1.5
  AND i_clicker.nums / book.nums < 2 THEN '四星服务'
  WHEN i_clicker.nums / book.nums >= 2 THEN '五星服务'
  ELSE '-'
  END AS i_clicker_rank
  FROM
  --  (
  --     SELECT ins_id, 1 AS flag
  --     FROM dm_ins_info
  --     GROUP BY ins_id
  -- )
  ins
  LEFT OUTER JOIN
    (
      SELECT year, period, 1 AS flag
      FROM tmp_marketing_metrics_book_rank_config
      WHERE start_time <= '${bdp.system.bizdate}'
    )
  tmmbrc
  ON ins.flag = tmmbrc.flag
    LEFT OUTER JOIN (
      SELECT /*+ mapjoin(tmmbrc)*/
      dtoi.ins_id, SUM(dtoi.num) AS nums, tmmbrc.year, tmmbrc.period
      FROM (
        SELECT year, period, 1 AS flag
        FROM tmp_marketing_metrics_book_rank_config
        WHERE start_time <= '${bdp.system.bizdate}'
      )
      tmmbrc
      LEFT OUTER JOIN
      (
        SELECT *, 1 AS flag
        FROM dm_textbook_order
        WHERE line = '主线'
        AND status != '已取消'
        AND goods_name NOT LIKE '%外研英语%'
        ) dtoi
          ON dtoi.flag = tmmbrc.flag
      WHERE tmmbrc.period IN (dtoi.spring_season, dtoi.summer_season, dtoi.autumn_season, dtoi.winter_season)
      AND dtoi.textbook_order_year = tmmbrc.year
      GROUP BY dtoi.ins_id,
      tmmbrc.year,
      tmmbrc.period
    ) book
      ON ins.ins_id = book.ins_id
    AND tmmbrc.year = book.year
    AND tmmbrc.period = book.period
  LEFT OUTER JOIN(
    SELECT /*+ mapjoin(tmmbrc) */
    tmmbrc.year, tmmbrc.period, ddsa.ins_id,
    COUNT(DISTINCT ddsa.student_id) AS nums
    FROM  (
      select * from tmp_marketing_metrics_book_rank_config
      where  period IS NOT NULL
    ) tmmbrc
    LEFT OUTER JOIN dm_dt_schedule_answer ddsa
      ON SUBSTR(tmmbrc.period, 1, 1) = ddsa.period
        AND to_char(ddsa.start_time, 'yyyymmdd') >= tmmbrc.start_time
        AND to_char(ddsa.start_time, 'yyyymmdd') < tmmbrc.end_time
    GROUP BY tmmbrc.year,
    tmmbrc.period,
    ddsa.ins_id,
    ddsa.period
  ) i_clicker
    ON ins.ins_id = i_clicker.ins_id
      AND tmmbrc.year = i_clicker.year
      AND tmmbrc.period = i_clicker.period
)
--------------------------------------营销指标体系-------------------------------------------
INSERT OVERWRITE TABLE bi_marketing_metrics_ins_info
  SELECT
  book.ins_id, book.ins_code, book.ins_name, book.year, book.period
  , book.book_rank, book.ins_area_level, book.ins_emp_number_level
  , COALESCE(sk_duration.avg_duration_rank, '-'), health.expand_rate
  , health.permeate_rate, health.incre_rate, tt.tt_rank, asd.as_rank, i_clicker.i_clicker_rank
  , book.book_nums, cast(book.ins_emp_number as bigint) as ins_emp_number, COALESCE(sk_duration.avg_duration_hour, 0) AS avg_duration_hour
  ,cast(COALESCE(sk_duration.avg_duration_minute, 0) as bigint)AS avg_duration_minute
  FROM t_marketing_metrics_book_rank book
  LEFT OUTER JOIN t_marketing_metrics_sk_duration_week sk_duration
    ON book.ins_id = sk_duration.ins_id
      AND book.year = sk_duration.year
      AND book.period = sk_duration.period
  LEFT OUTER JOIN t_marketing_metrics_health_degree health
    ON book.ins_id = health.ins_id
      AND book.year = health.year
      AND book.period = health.period
  LEFT OUTER JOIN t_marketing_metrics_service_degree_tt tt
    ON book.ins_id = tt.ins_id
      AND book.year = tt.year
      AND book.period = tt.period
  LEFT OUTER JOIN t_marketing_metrics_service_degree_as asd
    ON book.ins_id = asd.ins_id
      AND book.year = asd.year
      AND book.period = asd.period
  LEFT OUTER JOIN t_marketing_metrics_service_degree_i_clicker i_clicker
    ON book.ins_id = i_clicker.ins_id
      AND book.year = i_clicker.year
      AND book.period = i_clicker.period;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值