K87L8BZBS6

DWH-1179

Dec 24th, 2024
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --- Отформатированный код из задачи. Добавил только `lesson_id` в сортировку для того, чтобы создать детерминированную сортировку ---
  2. CREATE TEMP TABLE original_report AS
  3. WITH needed_lessons AS (
  4.     SELECT
  5.         tutor_id,
  6.         lesson_id,
  7.         lesson_state,
  8.         start_time,
  9.         pupil_id,
  10.         -- Пометим флагом своеврем/несвоеврем отмены и прогулы. Всегда опираемся на статус урока первым делом.
  11.         -- Если статус cancelled и первый отменивший - препод, ставим флаг своевременной отмены.
  12.         COALESCE(lesson_state = 'cancelled' AND cancellation_made_by_role = 'tutor', FALSE)::INT AS is_ok_tutor_cancel,
  13.         -- Если статус прогул П/обоих и есть попытка отмены до начала урока - поздняя отмена преподавателем.
  14.         COALESCE(lesson_state IN ('tutor_no_show', 'both_no_show')
  15.                  AND first_cancellation_datetime < start_time, FALSE)::INT AS is_late_tutor_cancel,
  16.         -- Если статус прогул П/обоих и нет попытки отмены до начала урока - прогул преподавателя.
  17.         COALESCE(lesson_state IN ('tutor_no_show', 'both_no_show')
  18.                  AND (first_cancellation_datetime >= start_time OR first_cancellation_datetime IS NULL), FALSE)::INT AS is_no_tutor_cancel,
  19.         -- Найдем последние 50 уроков преподавателя в любом статусе.
  20.         ROW_NUMBER() OVER (PARTITION BY tutor_id ORDER BY start_time DESC, lesson_id) AS rn_tutor_desc
  21.     FROM
  22.         mart.events_with_lessons
  23.     WHERE
  24.         manager_of_intro_lesson IS FALSE
  25.         AND is_regular_lesson + is_intro_lesson = 1
  26.         AND lesson_state != 'new'
  27.         AND lesson_state IS NOT NULL
  28.         AND is_tetrika_lesson IS TRUE
  29.         AND start_time < '2024-12-01'
  30. ),
  31. -- Посчитаем количество отмен с одним учеником.
  32. finding_cancels_with_same_pupil AS (
  33.     SELECT
  34.         tutor_id,
  35.         lesson_id,
  36.         pupil_id,
  37.         start_time,
  38.         lesson_state,
  39.         -- Найдем количество "плохих" уроков с одним учеником.
  40.         COUNT(lesson_id) OVER (PARTITION BY tutor_id, pupil_id ORDER BY start_time DESC, lesson_id) AS bad_lessons_with_pupil_count
  41.     FROM
  42.         needed_lessons
  43.     WHERE
  44.         (is_ok_tutor_cancel + is_late_tutor_cancel + is_no_tutor_cancel) > 0
  45. ),
  46. all_cancels_together AS (
  47.     SELECT
  48.         needed_lessons.tutor_id,
  49.         needed_lessons.lesson_id,
  50.         needed_lessons.lesson_state,
  51.         needed_lessons.start_time,
  52.         needed_lessons.pupil_id,
  53.         needed_lessons.is_ok_tutor_cancel,
  54.         needed_lessons.is_late_tutor_cancel,
  55.         needed_lessons.is_no_tutor_cancel,
  56.         needed_lessons.rn_tutor_desc,
  57.         -- Где есть информация о прогулах с одним учеником, возьмем её. Где нет - подставим 0.
  58.         COALESCE(finding_cancels_with_same_pupil.bad_lessons_with_pupil_count, 0) AS bad_lessons_with_pupil_count,
  59.         -- Итоговую стоимость каждого прогула рассчитываем так:
  60.         -- своевременная отмена - вес 1, несвоевременная отмена - вес 1.5, прогул - вес 2.
  61.         -- Если несколько плохих уроков с одним учеником, то каждый последующий плохой урок весит больше:
  62.         -- 1-й как 1, второй - как 2, третий - как 3.
  63.         is_ok_tutor_cancel * 1 * COALESCE(finding_cancels_with_same_pupil.bad_lessons_with_pupil_count, 0) +
  64.         is_late_tutor_cancel * 1.5 * COALESCE(finding_cancels_with_same_pupil.bad_lessons_with_pupil_count, 0) +
  65.         is_no_tutor_cancel * 2 * COALESCE(finding_cancels_with_same_pupil.bad_lessons_with_pupil_count, 0) AS final_score
  66.     FROM
  67.         needed_lessons
  68.     LEFT JOIN
  69.         finding_cancels_with_same_pupil USING (lesson_id)
  70. )
  71. SELECT *
  72. FROM all_cancels_together;
  73.  
  74.  
  75. --- Тестовая таблица, данные ограничены фильтром `clean.events.start_time < '2024-12-01'` ---
  76. DROP TABLE IF EXISTS dwh_report;
  77. CREATE TEMP TABLE dwh_report AS
  78. SELECT
  79.     dwh_1179_core_tutor_lesson_counter.tutor_id,
  80.     dwh_1179_core_tutor_lesson_counter.lesson_id,
  81.     dwh_1179_core_tutor_lesson_counter.lesson_started_at,
  82.     dwh_1179_core_tutor_lesson_counter.tutor_lesson_number_desc,
  83.     dwh_1179_core_tutor_lesson_counter.lesson_number_without_tutor_present,
  84.     dwh_1179_core_tutor_lesson_counter.discipline_score
  85. FROM sandbox.dwh_1179_core_tutor_lesson_counter
  86. JOIN core.lessons
  87.     ON lessons.lesson_id = dwh_1179_core_tutor_lesson_counter.lesson_id;
  88.  
  89. ---  Проверяем есть ли лишние записи ---
  90. SELECT *
  91. FROM original_report
  92. FULL JOIN dwh_report
  93.     ON original_report.lesson_id = dwh_report.lesson_id
  94. WHERE TRUE = TRUE
  95.     AND original_report.lesson_id IS NULL
  96.     AND dwh_report.tutor_lesson_number_desc IS NOT NULL;
  97.  
  98. --- Проверяем матчатся ли поля с кодом из задачи ---
  99. SELECT
  100.     original_report.lesson_id,
  101.     dwh_report.lesson_id,
  102.  
  103.     original_report.start_time,
  104.     dwh_report.lesson_started_at,
  105.  
  106.     original_report.rn_tutor_desc,
  107.     dwh_report.tutor_lesson_number_desc,
  108.  
  109.     original_report.bad_lessons_with_pupil_count,
  110.     dwh_report.lesson_number_without_tutor_present,
  111.  
  112.     original_report.final_score,
  113.     dwh_report.discipline_score
  114.  
  115. FROM original_report
  116. LEFT JOIN dwh_report
  117.     ON original_report.lesson_id = dwh_report.lesson_id
  118. WHERE
  119.     original_report.rn_tutor_desc IS DISTINCT FROM dwh_report.tutor_lesson_number_desc
  120.     OR original_report.bad_lessons_with_pupil_count IS DISTINCT FROM dwh_report.lesson_number_without_tutor_present
  121.     OR original_report.final_score IS DISTINCT FROM dwh_report.discipline_score;
  122.  
Advertisement
Add Comment
Please, Sign In to add comment