Про SQL Wildcards
Я решила поэкспериментировать с форматом и посмотреть, что из этого выйдет)
⭐ Все знают про %, но про остальные я думала, что они существуют в регулярках в программировании, но никак не в эскуэль.
Пока не увидела в коде запросов, например:
Для любителей почитать вот ссылки на оф. доки:
Postgres
MS SQL Server
MySQL
#sql_tips
Я решила поэкспериментировать с форматом и посмотреть, что из этого выйдет)
Пока не увидела в коде запросов, например:
--эквивалентны
and Action_Code like 'K[HS]'
and Action_Code = 'KH' or Action_Code = 'KS'
--тоже эквивалентны
and Assignment_Value like '%CRE[12]%'
and Assignment_Value like '%CRE1%' or Assignment_Value like '%CRE2%'
Для любителей почитать вот ссылки на оф. доки:
Postgres
MS SQL Server
MySQL
#sql_tips
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥30⚡2👨💻2💯1
count(), F.count(), F.countDistinct(), distinct()
В спарке есть несколько функций count, которые меня вначале путали, и тут я хочу расставить все точки над i.
1️⃣ count() - это действие
Оно запустит весь пайплайн расчетов и выведет на экран одно число - количество строк в датафрейме:
Также можно использовать в агрегации, но нельзя поменять название столбца (будет count):
2️⃣ F.count() - это трансформация, агрегирующая функция
В отличие от первого способа в агрегации можно поменять название столбца:
Отличия count() и F.count():
3️⃣ F.countDistinct() - тоже агрегирующая функция
Тут вариант агрегации только один, потому что df.countDistinct() не существует:
При этом в спарке есть еще функция distinct(), которая тоже вносит некую путаницу.
Отличия distinct().count() и F.countDistinct():
#spark
В спарке есть несколько функций count, которые меня вначале путали, и тут я хочу расставить все точки над i.
Оно запустит весь пайплайн расчетов и выведет на экран одно число - количество строк в датафрейме:
df.count()
Также можно использовать в агрегации, но нельзя поменять название столбца (будет count):
df.groupBy('category')
.count()
.orderBy('count')
.show()df.select(F.count('id')).show()В отличие от первого способа в агрегации можно поменять название столбца:
df.groupBy('category')
.agg(F.count('id').alias('cnt'))
.orderBy('cnt')
.show()Отличия count() и F.count():
# результат - датафрейм с одной ячейкой
df1.select(F.count('id')).show()
# +---------+
# |count(id)|
# +---------+
# | 3|
# +---------+
# результат - число
df1.select('id').count()
# 3
df.select(F.countDistinct('id')).show()Тут вариант агрегации только один, потому что df.countDistinct() не существует:
df.groupBy('category')
.agg(F.countDistinct('id'))
.show()При этом в спарке есть еще функция distinct(), которая тоже вносит некую путаницу.
Отличия distinct().count() и F.countDistinct():
# результат - датафрейм с одной ячейкой
df1.select(F.countDistinct('id')).show()
# +------------------+
# |count(DISTINCT id)|
# +------------------+
# | 2|
# +------------------+
# результат - число
df1.select('id').distinct().count()
# 2
#spark
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥5🌚1
Как из деления int/int получить double?
🤓 Вам нужно что-то посчитать: поделить одно количество на другое и округлить результат до 2х знаков после запятой.
Так как количество - это целое число, если написать просто count1/count2, то в результате мы получим тоже целое число: 15/26 = 0. А мы хотим 0.57692307692307692308 - вот оно самое.
✨ Поэтому умножаем на 1.0, и вуаля✨
#sql_tips
Так как количество - это целое число, если написать просто count1/count2, то в результате мы получим тоже целое число: 15/26 = 0. А мы хотим 0.57692307692307692308 - вот оно самое.
SELECT round(count1 * 1.0 / count2, 2)
FROM test
#sql_tips
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12❤3🌚2
Сегодня у нас прошло очередное демо трайба!
Команда
В кластере несколько команд, а в трайбе несколько кластеров (всего где-то 15 команд +-).
Что было?
Ну, и вкусный фуршетик
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12❤3😁2🆒1
В продолжение поста про вредные советы есть еще несколько лайфхаков (уже нормальных!):
SELECT
e.emp_no
, e.first_name
--, e.last_name
, s.salary
FROM employees e
JOIN salaries s
ON e.emp_no = s.emp_no
final_df = (
employees.alias('e')
.join(salaries.alias('s'), F.col('e.emp_no') == F.col('s.emp_no'), 'inner')
.select(
'e.emp_no',
'e.first_name',
's.salary'
)
)
1=1, чтобы тоже быстро закомментить и прогнать:SELECT *
FROM employees
WHERE 1=1
--AND date_joined <= '2024-01-01'
AND is_deleted = 0
AND username != 'system'
Если бы
WHERE date_joined <= '2024-01-01' шло на первом месте, то пришлось бы убирать AND перед вторым условием, удалять лишние пробелы - в общем, неудобно, если часто так делать.#sql_tips #spark
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👏4💯2
Задачка
Есть 3 таблички:
1️⃣ Cities (id, city, region)
2️⃣ Couriers (id, fio)
3️⃣ Orders (id, datetime, cost, city_id, courier_id)
Найти топ 10 курьеров для каждого города, которые доставили больше всего заказов за март.
Есть 3 таблички:
Найти топ 10 курьеров для каждого города, которые доставили больше всего заказов за март.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥2
Домашку проверила) В целом, у всех плюс-минус похожие варианты
Отметила несколько моментов:
--тут не войдет 31 число
WHERE datetime >= '2024-03-01' AND datetime < '2024-03-31'
--тут за 31.03 войдет только 00:00:00
WHERE datetime between '2024-03-01' AND '2024-03-31'
--поэтому так правильнее
WHERE datetime > '2024-03-01' AND datetime < '2024-04-01'
Ну, и всякие extract/date_part тоже подойдут.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👌1
Помогите закрыть таску!😘
💻 Исходные данные
У нас есть три вьюшки с id и json-полем. Вьюшки собираются по разным фильтрам.
📌 Цель: собрать массив степов, при этом дополнить предыдущие недостающие степы значением default_json.
🎥 Пример:
для id = 1: [json]
для id = 2: [default_json, json]
для id = 3: [default_json, default_json, json]
и т.д.
При этом в default_json прокидывается текущий степ, поэтому нам нужно не потерять это название.
🚀 Пока идея такая:
- делаем full join
- делаем unpivot
- добавляем флаг is_missed на основе null
- итерируемся с конца в рамках id и удаляем все is_missed = 1, пока не найдём is_missed = 0
Лично мне это кажется слишком громоздкий и малочитаемым, поэтому хочется двинуться в сторону unuon, но тогда теряется текущий степ. Или после джойна в рамках строки как-то найти последнее заполненное поле.
🤩 Any ideas?
У нас есть три вьюшки с id и json-полем. Вьюшки собираются по разным фильтрам.
для id = 1: [json]
для id = 2: [default_json, json]
для id = 3: [default_json, default_json, json]
и т.д.
При этом в default_json прокидывается текущий степ, поэтому нам нужно не потерять это название.
- делаем full join
- делаем unpivot
- добавляем флаг is_missed на основе null
- итерируемся с конца в рамках id и удаляем все is_missed = 1, пока не найдём is_missed = 0
Лично мне это кажется слишком громоздкий и малочитаемым, поэтому хочется двинуться в сторону unuon, но тогда теряется текущий степ. Или после джойна в рамках строки как-то найти последнее заполненное поле.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5⚡1
На этих выходных я сходила на сходку аналитиков, где мы пообщались на разные темы и поделились своими мнениями.
Потом обсудили несколько резюме. На всякий случай я писала заметки себе на будущее, и вот что туда попало:
- что делал
- чем делал (инструменты)
- какая была цель
- какой результат и вэлью
Результатом может быть увеличение хорошей метрики, уменьшение плохой метрики или стабилизация/сохранение какой-то метрики.
Я сформулировала это так: все continuous задачи перевести в done.
Обсудили свои планы, идеи, решения, что я прямо замотивировалась встать и начать делать!
Всего мы просидели 6 часов, но я немного огорчилась, что так мало!
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19❤9❤🔥4💯2
Логика с json'ами
На прошлой неделе я вкидывала задачу. Мы ещё раз пообсуждали и вот на чем остановились:
1️⃣ Делаем фулл джойн исходных витрин: view1, view1_1, ...
Идею с кросс джойнами мы решили оставить)
2️⃣ Делим фулловую таблицу на n вьюшек, где n - это количество шагов. Начинаем с конца (последнего заполненного).
Пример:
when step1_2 is not null => v_step1_2 - новая вьюшка для строк, у которых есть степ1_2:
3️⃣ Делаем left anti join фулловой таблицы с созданной вьюшкой, получаем строки, которые не вошли:
Повторяем шаги 2 и 3 n раз.
NB! В следующих вьюшках количество столбцов уменьшается (исключаем уже выделенный степ)
1) when step1_1 is not null => v_step1_1
После left anti join обновленная фулловая:
На последнем этапе просто берем id и первый столбец.
Итак, у нас 3 вьюшки с разным количеством столбцов.
️4️⃣ Делаем coalesce(stepn, default_json)
5️⃣ Делаем array(всех шагов) => получаем одинаковую структуру для всех вьюшек с полями id и array
6️⃣ Union
🕺 🕺 🕺 🕺 🕺 🕺 🕺
На прошлой неделе я вкидывала задачу. Мы ещё раз пообсуждали и вот на чем остановились:
Идею с кросс джойнами мы решили оставить)
Пример:
when step1_2 is not null => v_step1_2 - новая вьюшка для строк, у которых есть степ1_2:
3 null null json
5 json null json
6 null json json
7 json json json1 json null null
2 null json null
4 json json null
Повторяем шаги 2 и 3 n раз.
NB! В следующих вьюшках количество столбцов уменьшается (исключаем уже выделенный степ)
1) when step1_1 is not null => v_step1_1
2 null json
4 json json
После left anti join обновленная фулловая:
1 json null nullНа последнем этапе просто берем id и первый столбец.
Итак, у нас 3 вьюшки с разным количеством столбцов.
️
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯8🔥3🆒3
Написала статью про планы запросов!
Пару месяцев лежала в бэклоге, месяц собиралась в голове, 3 дня писалась, и теперь она здесь)
Сесть и сделать сподвигла последняя дз по курсу амбассадоров. Там был выбор между статьёй и подкастом. Но до подкастов я как-нибудь тоже доберусь)
https://habr.com/ru/articles/807421/
Пару месяцев лежала в бэклоге, месяц собиралась в голове, 3 дня писалась, и теперь она здесь)
Сесть и сделать сподвигла последняя дз по курсу амбассадоров. Там был выбор между статьёй и подкастом. Но до подкастов я как-нибудь тоже доберусь)
https://habr.com/ru/articles/807421/
Хабр
Spark. План запросов на примерах
Всем привет! В этой статье возьмем за основу пару таблиц и пройдемся по планам запросов по нарастающей: от обычного селекта до джойнов, оконок и репартиционирования. Посмотрим, чем отличаются виды...
🔥26❤🔥5 4
Теория или практика?
📖 Наконец-то прочитала книжку "Spark в действии". Очень понравился вот этот рисунок: он супер понятно описывает суть ленивых вычислений) Spark копит все преобразования над данными, пока что-то не заставит его запустить весь пайплайн (например, show).
Отметила для себя пару новых моментов:
1️⃣ Можно создать табличку через sql и сразу перевести её в датафрейм (я думала, что такое работает только для реальных таблиц)
Например:
2️⃣ Есть интересные методы сортировки asc_nulls_first, asc_nulls_last (для desc так же), чтобы обозначить порядок для нуллов
🐰 Ещё позабавили некоторые формулировки)
Надеюсь, что это трудности перевода))
🐱 Вообще пришло осознание, что теоретические книжки легко читаются, когда ты уже пощупал это на практике.
А вы как считаете, когда нужно читать умные книжки?
#spark
Отметила для себя пару новых моментов:
Например:
spark.sql(
'select id from users'
) \
.createOrReplaceTempView('view_users')
df_users = spark.table('view_users')
"Агрегации - ... в известной степени приближение к методам машинного обучения и искусственного интеллекта".
"Во время моей работы со Spark я встречал два типа людей: тех, кто имел опыт работы с Apache Hadoop, и тех, у кого не было такого опыта".
Надеюсь, что это трудности перевода))
А вы как считаете, когда нужно читать умные книжки?
#spark
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17 8❤🔥4