1 of 40

Data Engineer. Лекция 3

  • Лектор: Анатолий Бардуков�
  • tg для связи: @sindb , либо в чате��

Наливайте чай,

приветствуйте друг друга в чате и приготовьтесь хорошо провести время

2 of 40

Про что сегодня �расскажем

  • Финализируем SQL
  • Slowly Changing Dimensions aka SCD
  • ДЗ1
  • Работа с датами, текстами и regexp в SQL
  • Обсудим проект

Наливайте чай,

приветствуйте друг друга в чате и приготовьтесь хорошо провести время

3 of 40

Представление (на сленге «вьюха») – SQL код, сохраненный в справочнике базы данных под своим собственным именем. Данный код исполняется каждый раз при обращении к представлению. Обратите внимание, что представление само по себе не хранит данные, только SQL код.

​

Представления используются для двух целей:

  • замаскировать нежелательные данные (best practice)
  • спрятать в представление бизнес-логику (worth practice)

​

CREATE VIEW SchemaName.ViewName AS

SELECT * FROM SchemaName.TableName;

CREATE OR REPLACE VIEW SchemaName.ViewName AS

SELECT * FROM SchemaName.TableName WHERE 1=1;

DROP VIEW SchemaName.ViewName;

​

SQL. Представления

Создайте представление над таблицей hr.employees, скрывающее данные о зарплате сотрудников. В представлении должны быть поля first_name, last_name, email, phone_number.

4 of 40

SQL. Подзапросы

4-3. Руководитель хочет выплатить премию всем сотрудникам подразделений, перечисленных в таблице hr.dep_bonus. Выведите список таких сотрудников из таблицы hr.employees, воспользовавшись только подзапросами.

​

Пример использования подзапроса – вывести всех сотрудников, кто работает продажниками (в названии работы есть слово «Sales»):

​

SELECT

*

FROM hr.employees

WHERE job_id IN (

SELECT

job_id

FROM hr.jobs

WHERE job_title LIKE 'Sales%'

);

​

5 of 40

Common Table Expression

WITH cte_name (column_list) AS (

CTE_query_definition

),

cte_name2 (column_list) AS (

CTE_query_definition

)

statement;

​

  1. CTE_query_definition - некоторый запрос select
  2. statement - DML запрос, в нём можно обращаться к cte_name

​

Временная таблица, которая существует только во время выполнения запроса

​

6 of 40

SQL. Группировка и агрегатные функции

  1. Среди работников, не имеющих процента от прибыли, какова максимальная зарплата?
  2. Пересчитайте зарплату работникам. Если работник из IT отдела – добавьте 15%.
  3. Выведите название отделов с количеством сотрудников больше среднего.
  4. Найдите имена и фамилии сотрудников с максимальной зарплатой в каждом департаменте hr.employees.
  5. Выведите заказы, содержащие 5 и более позиций.
  6. Выведите список сотрудников, не оформивших ни одного заказа.

7 of 40

SELECT * FROM SchemaName.TableName1

UNION [ALL]

SELECT * FROM SchemaName.TableName2;

​

SQL. Вертикальное соединение таблиц

1. Сделайте копию таблицы hr.employees.

2. Соедините вашу копию и таблицу hr.employees с помощью запроса выше без указания ALL и с указанием ALL. В чем разница?

3. Попробуйте соединить несоединимое.

​

8 of 40

JOIN quiz

1. Есть две таблицы, в одной из них 10 записей, в другой – 100. Какое минимальное и максимальное количество записей можно получить используя разные виды соединений?

​

9 of 40

2. Соедините две таблицы всеми видами соединений (без CROSS JOIN). Соединение происходит следующим шаблоном запроса:

SELECT Table1.ID ID_1, Table2.ID ID_2

FROM Table1

<вид соединения> JOIN Table2

ON Table1.ID = Table2.ID;

JOIN quiz

Table1

​

Table2

ID

​

ID

1

​

2

2

​

null

3

​

3

4

​

3

null

​

5

​

​

null

​

​

​

​

​

​

​

​

​

10 of 40

2. Соедините две таблицы всеми видами соединений (без CROSS JOIN). Соединение происходит следующим шаблоном запроса:

SELECT Table1.ID ID_1, Table2.ID ID_2

FROM Table1

<вид соединения> JOIN Table2

ON Table1.ID = Table2.ID;

JOIN quiz

Table1

​

Table2

​

Result (inner)

ID

​

ID

​

ID_1

ID_2

1

​

2

​

2

2

2

​

null

​

3

3

3

​

3

​

3

3

4

​

3

​

​

​

null

​

5

​

​

​

​

​

null

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

11 of 40

2. Соедините две таблицы всеми видами соединений (без CROSS JOIN). Соединение происходит следующим шаблоном запроса:

SELECT Table1.ID ID_1, Table2.ID ID_2

FROM Table1

<вид соединения> JOIN Table2

ON Table1.ID = Table2.ID;

JOIN quiz

Table1

​

Table2

​

Result (left)

ID

​

ID

​

ID_1

ID_2

1

​

2

​

2

2

2

​

null

​

3

3

3

​

3

​

3

3

4

​

3

​

1

null

null

​

5

​

4

null

​

​

null

​

null

null

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

12 of 40

2. Соедините две таблицы всеми видами соединений (без CROSS JOIN). Соединение происходит следующим шаблоном запроса:

SELECT Table1.ID ID_1, Table2.ID ID_2

FROM Table1

<вид соединения> JOIN Table2

ON Table1.ID = Table2.ID;

JOIN quiz

Table1

​

Table2

​

Result (right)

ID

​

ID

​

ID_1

ID_2

1

​

2

​

2

2

2

​

null

​

3

3

3

​

3

​

3

3

4

​

3

​

null

null

null

​

5

​

null

5

​

​

null

​

null

null

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

13 of 40

2. Соедините две таблицы всеми видами соединений (без CROSS JOIN). Соединение происходит следующим шаблоном запроса:

SELECT Table1.ID ID_1, Table2.ID ID_2

FROM Table1

<вид соединения> JOIN Table2

ON Table1.ID = Table2.ID;

JOIN quiz

Table1

​

Table2

​

Result (full)

ID

​

ID

​

ID_1

ID_2

1

​

2

​

2

2

2

​

null

​

3

3

3

​

3

​

3

3

4

​

3

​

1

null

null

​

5

​

4

null

​

​

null

​

null

null

​

​

​

​

null

null

​

​

​

​

null

5

​

​

​

​

null

null

14 of 40

Горизонтальное соединение. JOINs. CROSS JOIN.

SELECT * FROM TableName1

CROSS JOIN TableName2

​

SELECT * FROM TableName1, TableName2

​

15 of 40

SQL. Задачи на соединения

  1. Выведите список покупателей (фамилия, имя) старше 50 лет, накупивших в магазине более чем на 100000 долларов. (oe.customers, oe.orders)
  2. Выведите список всех сотрудников (фамилия, имя) и сколько заказов он обработал. (hr.employees, oe.orders)
  3. Выведите имена покупателей и количество заказов, которые он сделал. (oe.customers, oe.orders)
  4. Выведите имена всех покупателей и количество мониторов, которые они купили. (oe.customers, oe.orders, oe.order_items, oe.product_information)
  5. Выведите все заказы и количество проданных CPU D400 в них. (oe.orders, oe.order_items, oe.product_information)
  6. Выведите список (фамилия, имя сотрудника) и их

начальников (фамилия, имя). (hr.employees)

  1. Напишите запрос, который покажет имя и фамилию

сотрудников, которые получают заработную плату больше

своего менеджера. (hr.employees)

  1. Выведите список сотрудников отдела продаж, кто не

совершил ни одной продажи в марте 2007 года.

(hr.employees, oe.orders)

16 of 40

SQL. Группировка и агрегатные функции

Пример. Сколько сотрудников в каждом отделе?

SELECT

DepartmentID,

COUNT(*) as Kolichestvo

FROM hr.employees

GROUP BY DepartmentID;

​

Пример. В каких отделах больше 5 работников?

SELECT

DepartmentID,

COUNT(*) as Kolichestvo

FROM hr.employees

GROUP BY DepartmentID

HAVING COUNT(*) > 5;

17 of 40

Аналитические (оконные) функции

Синтаксис оконной функции:

​

analytic_function() OVER (

[PARTITION BY expression1, expression2,...]

ORDER BY expression1 [ASC | DESC], expression2,... )

​

SELECT

SUM( value ) OVER( ORDER BY value ) rn

FROM

OrderDetails;

​

SELECT

SUM(value1) OVER(PARTITION BY id ORDER BY value1) value2

FROM

OrderDetails;

​

Наиболее употребляемые аналитические функции:

AVG, COUNT, DENSE_RANK, FIRST_VALUE, LAG, LAST_VALUE,

LEAD, MAX, MEDIAN, MIN, RANK, ROW_NUMBER, SUM

​

18 of 40

Аналитические функции. Окно.

19 of 40

Аналитические (оконные) функции

  1. В таблице de.cycling лежат результаты 20 этапа Тур де Франс. Расставьте места. Воспользуйтесь разными функциями и сравните результат.
  2. Вычислите накопительную сумма для счета клиента.
  3. Выведите имена покупателей (oe.customers), которые совершили заказ (oe.orders) с возрастанием суммы (более поздний заказ на большую сумму, чем более ранний).

​

Синтаксис оконной функции:

​

analytic_function() OVER (

[PARTITION BY expression1, expression2,...]

ORDER BY expression1 [ASC | DESC], expression2,... )

​

SELECT

SUM(value1) OVER(PARTITION BY id ORDER BY value1) value2

FROM

OrderDetails;

​

Наиболее употребляемые аналитические функции:

AVG, COUNT, DENSE_RANK, FIRST_VALUE, LAG, LAST_VALUE,

LEAD, MAX, MEDIAN, MIN, RANK, ROW_NUMBER, SUM

​

20 of 40

SCD версионность

SCD0

​

​

Неизменяемые данные

​

21 of 40

SCD версионность

SCD1

​

​

​

​

22 of 40

SCD версионность

SCD2

​

​

​

​

23 of 40

SCD версионность

SCD2

​

​

​

​

24 of 40

Типовые действия с форматом SCD2

  • Выделение актуального среза
  • Выделение среза на дату
  • Создание таблицы SCD2 на основе фактовой таблицы
  • Соединение фактовой таблицы и SCD2 таблицы
  • Операция HistGroup
  • Операция HistMerge
  • Операция FDTD join

​

25 of 40

SCD версионность. Задача

26 of 40

*** FDTD join

27 of 40

Логические удаления

28 of 40

Актуальный (активный) срез

29 of 40

Домашнее задание 1

Часть 1

​

Создайте структуру базы данных по предложенной тематике

​

К базе данных предъявляются следующие требования:

  • должно быть не менее 4 сущностей (включая технические объекты);
  • должна быть хотя бы одна связь один-ко-многим;
  • должна быть хотя бы одна связь многие-ко-многим;
  • все отношения приведены к 3НФ.

​

Предметная область (выберите одно):

1. Продажа автомобилей.

2. Приют для животных.

3. Железнодорожные перевозки.

4. Служба доставки.

5. Организация марафона.

Требования к оформлению:

  • ER-диаграмму необходимо составлять на app.dbdesigner.net, на проверку нужно прислать ссылку на диаграмму
  • Также необходимо сделать SQL скрипт с DDL для создания таблиц (обращаем внимание на ограничения) и заполнение примерами данных

​

Наливайте чай,

приветствуйте друг друга в чате и приготовьтесь хорошо провести время

30 of 40

Часть 2

  1. Создайте таблицу ****_SALARY_HIST, где **** - ваш идентификатор. �В таблице должна быть SCD2 версия таблицы de.histgroup�(поля PERSON, CLASS, SALARY, EFFECTIVE_FROM, EFFECTIVE_TO).�
  2. Используйте таблицы ****_SALARY_HIST и de.salary_payments.�Напишите SQL скрипт, выводящий таблицу платежей сотрудникам. ��В таблице должны быть поля PAYMENT_DT, PERSON, PAYMENT, MONTH_PAID, MONTH_REST.�Результат выполнения сохраните в таблицу ****_SALARY_LOG.

• PAYMENT_DT - дата выплаты,

• MONTH_PAID - суммарно выплачено в месяце на дату последней выплаты,

• MONTH_REST - осталось выплатить за месяц.

Проверяется в первую очередь понимание как соединять фактовую таблицу с SCD2 таблицей (нельзя все расчеты сделать над de.salary_payments, ведь работнику могут недоплатить или переплатить).

В ответе приложите SQL скрипт, таблица ****_SALARY_LOG должна быть заполнена.

Пожалуйста, будьте внимательны к ТЗ (названия таблиц, полей, формат сдачи и т.п.)!

Дедлайн: 1 неделя с момента выдачи

31 of 40

SQL. Строковые функции

Возьмите в работу таблицу DE.BANK_CLIENTS. Создайте представ-ление XXXX_V_BANK_CLIENTS, выводящее фамилию и имя клиента одним полем, в формате с первой заглавной буквой; номер счета; замаскированный номер карты (маскировка обычно осуществляется путем замены цифр во второй и третьей группе на знак «*»), сумму на счете в формате 000001.23 (6 знаков перед точкой).

​

Функция

Назначение

lower( 'Example' )

Переводит все символы строки в нижний регистр ('example').

upper( 'Example' )

Переводит все символы строки в верхний регистр ('EXAMPLE').

initcap( 'example TWO' )

Переводит первый символ каждого слова в верхний регистр, остальные – в нижний ('Example Two’).

lpad( '1234', 8, '0' )

rpad( '1234', 8, '0' )

Дополняет строку из первого параметра строкой из третьего параметра до общей длины строки, указанной во втором параметре. Дополнение проводится слева и справа соответственно ('00001234', '12340000').

ltrim( ' ABC DEF ' )

rtrim( ' ABC DEF ' )

trim( ' ABC DEF ' )

Удаляет пробелы слева, справа, с обеих строн строки соответственно ('ABC DEF ', ' ABC DEF', 'ABC DEF').

32 of 40

SQL. Задачи на обработку строк

Приведите в порядок таблицу DE.DATASOURCE: корректно заполните поля first_name, last_name; разделите поле email на email и phone; телефон отформатируйте по маске +7 (123) 456-78-90; унифицируйте поле gender.�

Воспользуйтесь таблицами DE.BANK_CLIENTS и DE.BANK_TRANSACTIONS, на основании них создайте отчет по всем клиентам, в котором будут поля фамилия, имя и оборот за октябрь.

33 of 40

Очень коротко о регулярных выражениях

  1. Группы символов
    • [abcABC123]
    • [a-zA-Z0-9]
    • [^0-9]
    • (ABC|DEF)

​

​

  1. Специальные знаки
    • \w \W – буквы, цифры и знак _ (\W - не буквы/цифры/знак_)
    • \d \D – цифры (\D - не цифры)
    • \s \S – все пробельные символы (пробел, неразрывный пробел, табуляция)
    • ^ – начало строки
    • $ – конец строки
    • . – любой символ

​

​

Найдите сотрудников, у которых в имени есть одна из букв (a,f,r,t)

Найдите сотрудников, у которых имя начинается с одной из букв (a,f,r,t)

​

​

​

​

  1. Квантификаторы
    • + – один и больше
    • * – ноль и больше
    • {n} – ровно n
    • {n,m} – от n до m

​

​

34 of 40

SQL. Расширение строковых функций на регулярные выражения

Функция

Назначение

regexp_like( 'Year of 2017', '\d+’ )

'Year of 2017' ~ '\d+'

​

Поиск по регулярному выражению (возвращает «истина» или «ложь»).

regexp_count( 'Year of 2017 52', '\d+' )

Подсчет количества найденных вхождений регулярного выражения.

regexp_substr( 'Year of 2017', '\d+' )

regexp_match( 'Year of 2017', '\d+' )

​

Возвращает подстроку, найденную по регулярному выражению.

regexp_instr( 'Year of 2017', '\d+' )

Возвращает позицию найденной

подстроки по регулярному

выражению.

regexp_replace( 'Year of 2017', '\d+', 'Dragon’ )

regexp_replace( 'Year of 2017', '\d+', 'Dragon' )

Заменяет все вхождения, найденные

по регулярному выражению на

подстроку.

35 of 40

SQL. Задачи на обработку строк регулярными выражениями

  1. Таблица hr.employees. Выведите только те записи, в которых номер телефона имеет формат XXX.XXX.XXXX
  2. Таблица hr.departments. Выведите только те записи, у которых название департамента состоит не более, чем из 2 слов
  3. Создайте запрос, который позволяет найти строки с корректной электронной почтой.
  4. Найдите как можно больше валидных и как можно меньше невалидных номеров договоров и дат в таблице DE.PAYMENTS. Валидные реквизиты договора: 12345/67 от 21.01.2022, они приведены в поле reason_correct для самопроверки.

​

36 of 40

SQL. Задачи на обработку строк регулярными выражениями

  • Таблица hr.employees. Выведите только те записи, в которых номер телефона имеет формат XXX.XXX.XXXX
  • Таблица hr.departments. Выведите только те записи, у которых название департамента состоит не более, чем из 2 слов
  • Создайте запрос, который позволяет найти строки с корректной электронной почтой.��(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])�
  • Найдите как можно больше валидных и как можно меньше невалидных номеров договоров и дат в таблице DE.PAYMENTS. Валидные реквизиты договора: 12345/67 от 21.01.2022, они приведены в поле reason_correct для самопроверки.

​

37 of 40

Change data capture (CDC) – захват данных

Способы отследить происходящие изменения:

​

  • Отметка времени изменения
  • Числовая последовательность изменения (Oracle SCN, MS SQL LSN)
  • Флаг состояния («готов к захвату»)

​

  • Триггеры
  • Event processing
  • Сканеры логов

​

  • Никаких…

38 of 40

Пробуем собрать ETL�на SCD1

39 of 40

План

1. Очистка стейджинговых таблиц

2. Захват данных из источника (измененных с момента последней загрузки) в стейджинг

3. Захват в стейджинг ключей из источника полным срезом для вычисления удалений.

4. Загрузка в приемник "вставок" на источнике (формат SCD1).

5. Обновление в приемнике "обновлений" на источнике (формат SCD1).

6. Удаление в приемнике удаленных в источнике записей (формат SCD1).

7. Обновление метаданных.

8. Фиксация транзакции.

40 of 40

А как же SCD2?

  • Вставка – не изменяется.
  • Обновление атрибутов состоит из двух строк.
  • Удаление – добавление новой строки с DELETED_FLG = 1.

​

​

​

Обновим скрипт до SCD2 на следующем занятии