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 на следующем занятии