Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Регистрируясь, я даю согласие на обработку данных и условия почтовых рассылок.
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр Монстрикс — это динамичная стратегия, где ты собираешь, улучшаешь и сражаешься с могучими монстрами.

Монстрикс

Мидкорные, Стратегии, Мультиплеер

Играть

Топ прошлой недели

  • solenakrivetka solenakrivetka 7 постов
  • Animalrescueed Animalrescueed 53 поста
  • ia.panorama ia.panorama 12 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая «Подписаться», я даю согласие на обработку данных и условия почтовых рассылок.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
0 просмотренных постов скрыто
4
VelStyling
VelStyling
Серия Выгорела от работы аналитиком, но...

Поиск работы в конце 2025⁠⁠

2 часа назад

Сейчас декабрь, все закрывают квартал/год, делают бюджет на следующий год, но а я в поиске работы. Нет, начала поиск я не в декабре, а в октябре. Из результатов за 2 месяца - один оффер, но я отказалась от него. Не из-за содержания работы, а из-за процесса оформления - он вызвал сомнения.

И пока я продолжала поиск, я начала анализировать, что вообще происходит вокруг. Почему раньше всё работало одним способом, а теперь - совсем иначе.

Сейчас из каждого утюга слышу, что работу найти сложно, что на поиск работы надо закладывать 6 месяцев и т.д. и т.п. Ну ОК, подумала я, и вот в октябре начала искать, отрыла резюме на hh.ru для всех желающих, стала повторять теорию, нарешивать задачки и т.д.

Просматриваю вакансии, отбираю в избранное, потом анализирую, что и как там может быть. И наблюдаю за своим резюме. В итоге:
- просмотров резюме - кот наплакал,
- на отклики, релевантные моему опыту - отказы
- предложения только с релокацией в другую страну

Смотрю я статистику своего резюме: последний раз искала работу через HH в 2021 году, просмотров резюме по 10 в день. А сейчас дай бог 3 в неделю.

Резюме у меня одно, я его обновляю и дополняю по мере изменения моего опыта.

Читаю информацию про текущее положение на рынке, везде слышу, что рынок работодателя, что вакансий мало, резюме много. А дальше, очень часто натыкаюсь на то, что все разом говорят - надо делать резюме под конкретную вакансию

Причиной всего этого - автоматизация процессов. Первый скрининг резюме проводит не HR, а AI-агент, настроенный под конкретные триггерные слова.

Раньше мы писали резюме для людей.
Теперь - сначала для алгоритмов

Эпоха универсальных резюме закончилась.
Не потому, что специалисты стали хуже.
А потому что требования стали более структурированными, а инструменты поиска - более автоматизированными.

И теперь у меня вместо одного резюме - 4 резюме, с нотками особенностей под конкретные направления.

Опыт один и тот же.
Но фокус - разный.
И именно фокус видят алгоритмы.

И вот в этой статистике, которую вещает HH.ru - ссылка на презентацию здесь
Говорится о динамики среднего числа вакансий и резюме

Сопоставление вакансий идет к количеству резюме - не к количеству кандидатов.

Если даже возьмем меня, то у меня 4 резюме (планируется еще одно), т.е. количество резюме (в моем случае надо разделить на 4). А если это применить ко всем резюме, то может быть и картина то изменится. И не будем мы использовать слово рынок работодателя - а может быть другой рынок. Например рынок AI-ассистентов

Со стороны соискателей, тоже идет автоматизация. Соискатели в ручную откликаются на 100 вакансий из идеи - а что-то да и сработает. Либо также настраивают автоотклик, автообновление. Все это приводит к тому, что на одну вакансию HR-ы получают 400-3000 откликов, что руками нереально разобрать.

Поэтому компании:
- ставят автоскоринг
- ранжируют по ключевым словам
- убирают резюме, которые хоть чуть-чуть не совпадают
- сортируют по «свежести обновления»

И это не плохо и не хорошо — это новая норма.
Но к ней нужно адаптироваться.

Искать работу в конце 2025 года — это уже не про то, чтобы быть «идеальным кандидатом».
Это про то, чтобы быть заметным в мире, где первые фильтры проходят не люди, а алгоритмы.

Ну а я в своем канале про SQL буду продолжать делиться полезной информацией, интересными задачками и продолжать вдохновлять людей для изучения аналитики.
Если тебе интересно, подписывайся На связи: SQL

Этот канал я веду с нуля.

Показать полностью 1
[моё] Эмоциональное выгорание Опыт IT Поиск работы HH Аналитика Аналитик SQL Анализ данных Microsoft Excel База данных Длиннопост
8
3
viperinthebath
viperinthebath

Продолжение поста «Нужен совет по LibreOffice Base (SQL в том числе)»⁠⁠1

4 дня назад

Итак, решение найдено с помощью очень хорошего и талантливого человека, который тоже есть на Пикабу, но свело нас не Пикабу, а творчество. Огромное спасибо ей и за решение, и за творчество! Как и обещал ранее, публикую решение тут, вдруг кому пригодится. Запрос написан очень красиво и понятно, легко разобраться. ИМХО по таким примерам очень удобно изучать SQL. Да и @Avenir.Sirgun хотел взглянуть)))
Итак, вот запрос, который решает:

SELECT

YEAR(R.ДатаРасход) AS Год,

MONTH(R.ДатаРасход) AS Месяц,

A.Адрес,

M.НазваниеМатериал,

SUM(R.КолвоМатериала) AS Количество

FROM Расходы AS R

JOIN Работы AS W ON R.IDРабот = W.IDРабот

JOIN Адреса AS A ON W.IDАдреса = A.IDАдрес

JOIN Материалы AS M ON R.IDМатериала = M.IDМатериал

GROUP BY

YEAR(R.ДатаРасход),

MONTH(R.ДатаРасход),

A.Адрес,

M.НазваниеМатериал

ORDER BY

Год,

Месяц,

A.Адрес,

M.НазваниеМатериал;

Структура БД есть в изначальном посте.
Далее уже можно модифицировать, если надо.
Задача решена! Ура! Ещё раз огромное спасибо, В..., ты очень мне помогла! (не тегаю, т.к. не получал на то дозволения)

Показать полностью
[моё] Libreoffice База данных SQL Программирование Base IT Решение проблемы Ответ на пост Текст
0
3
viperinthebath
viperinthebath

Нужен совет по LibreOffice Base (SQL в том числе)⁠⁠1

8 дней назад

Друзья, задумал немного помочь себе и упростить работу. В свободное время решил соорудить базу данных выполненных работ по участку и потраченных на это материалов. Когда-то успешно делал себе "помогалки" в MS Access (в 90ых ещё), поэтому выбрал LibreOffice Base. Структура вот такая:

Таблицы БД со связями

Таблицы БД со связями

Форму для заполнения сделал. Заполняется, хранит данные. Отчёт по всем тратам отдельно создать - не проблема, получилось. Это без условий и без формул, просто списком.
Но никак не могу осилить отчёт, в котором бы выдавалась сумма по каждому адресу - сколько потрачено каждого вида материала. Типа,
Май:
Адрес1:
материал1 - 1
материал2 -3
Адрес2:
материал1 - 2
материал3 -4


Гуглил-яндексил, пытался по наитию, ничего не получается. Наверное, если просижу пару недель, изучая всё к ряду, то осилю... но подсказка бы ускорила.
Конечно, без рейтинга. Не знал, в какое сообщество отправить, но, надеюсь, не ошибся, ибо запрос-то на SQL писать придётся))) - долго ждать модерации, публикую без сообщества.
Заранее благодарен!
(Есть и второй вопрос - никак не могу придумать, как сделать типовые работы - чтобы кнопочку нажал, и автоматически заполнились поля формы, создались записи в таблице с расходами материалов)

Показать полностью 1
Libreoffice База данных SQL Без рейтинга
25
4
VelStyling
VelStyling
Серия SQL: знакомство

Условные выражения в запросах⁠⁠

28 дней назад

CASE WHEN - часто используемое условное выражение в запросах. Его особенности и факты далее.

Условные выражения в запросах

А пока подписывайся на мой канал На связи: SQL Там я публикую посты про особенности и нюансы SQL. Этот канал про то, как не бояться баз данных, понимать, что такое JOIN, GROUP BY и почему NULL ≠ 0. Его я веду с нуля подписчиков. Присоединяйся!

CASE - возвращает значение, но не управляет логикой выполнения запроса.

SELECT

name,

CASE

WHEN salary > 100000 THEN 'богач'

WHEN salary BETWEEN 50000 AND 100000 THEN 'норм'

ELSE 'бедняк'

END AS category

FROM employees;

Здесь CASE не «делает выборку», а вычисляет новое значение для каждой строки.

Где используется CASE

✅ В SELECT - чтобы выводить вычисленные поля
✅ В WHERE - чтобы сделать фильтрацию условной
✅ В ORDER BY - чтобы сортировать по кастомной логике
✅ В GROUP BY и HAVING - для агрегатов с условиями

Пример в ORDER BY:

ORDER BY

CASE WHEN status = 'vip' THEN 1 ELSE 2 END

В итоге VIP-клиенты окажутся первыми — без лишнего UNION или сортировки по тексту.

Где нельзя использовать CASE

  • Нельзя динамически подменять им названия колонок или таблиц — SQL так не работает:

SELECT * FROM CASE WHEN ... THEN table1 ELSE table2 END -- ошибка

  • Нельзя изменять структуру запроса — CASE не может выбирать, какие поля попадут в SELECT.

То есть он работает только на уровне данных, не на уровне схемы запроса.

Неочевидные факты

1. CASE возвращает первое совпадение

SQL идёт сверху вниз — как только условие совпало, остальные даже не проверяются.
Поэтому важно порядок условий.

CASE

WHEN score > 80 THEN 'A'

WHEN score > 90 THEN 'A+' -- никогда не сработает

END

Потому что >80 ловит всё, включая >90.

2. Тип результата — общий для всех веток

CASE пытается привести все результаты к единому типу.
Если ты вернёшь 'текст' и NULL, всё ок.
Но если 'текст' и 123, то SQL может выдать ошибку или привести число к строке.
💡 Всегда делай значения одного типа, особенно если потом используешь CASE в арифметике.

3. Есть две формы: сравнительная и поисковая

Обычно используют поисковую:

CASE WHEN condition THEN result ... END

Но есть ещё сравнительная:

CASE status

WHEN 'new' THEN 1

WHEN 'active' THEN 2

END

Она короче, но менее гибкая — работает только с равенством (=).

4. CASE + агрегаты = мощный аналитический трюк

Чтобы посчитать агрегаты по категориям в одной строке:

SELECT

SUM(CASE WHEN gender = 'M' THEN 1 ELSE 0 END) AS male_count,

SUM(CASE WHEN gender = 'F' THEN 1 ELSE 0 END) AS female_count

FROM users;

Один запрос, два счётчика, без подзапросов и джойнов.

5. CASE в WHERE — не всегда оптимален

Когда ты используешь CASE в WHERE, PostgreSQL часто не может применить индекс,
потому что условие становится непредсказуемым.

Пример:

WHERE

CASE WHEN is_vip THEN discount > 10 ELSE discount > 30 END

Лучше выносить логику в OR:

WHERE (is_vip AND discount > 10)

OR (NOT is_vip AND discount > 30)

Так планировщик сможет использовать индексы (их наличие подразумевается)

Где CASE особенно полезен

  • Когда нужно сделать динамическую сегментацию данных (категории, статусы, группы)

  • При построении витрин и отчётов (разделить аудиторию, выделить группы риска и т.п.)

  • Для чистки данных на лету (заменить NULL на текст или дефолтное значение)

  • В AB-тестах — присвоить группе метку на основании условия

Если тебе нравятся такие разборы SQL с реальными примерами и подводными камнями —
подписывайся на мой Telegram На связи: SQL

Показать полностью 1
[моё] SQL Microsoft Excel Аналитика Аналитик Анализ данных Самообразование Длиннопост
14
2
user5236465

Небольшой тренинг по XML в PostgreSQL на примере производственного календаря⁠⁠

1 месяц назад

Новый Год уже скоро, а значит нужен свежий производственный календарь в базе данных PostgreSQL. Но как совершенно обленившийся IT-шник, заводить его руками не хочется. Хочется, чтобы вызовом одной функции он сразу появился. Ну а уж из этой функции можно его сохранить в табличку и спокойно использовать до следующего Нового Года. А тогда опять просто вызвать функцию и с чистой совестью отрапортовать о выполненной работе. Моя цель - показать возможности COPY ... FROM PROGRAM и простейшие приемы парсинга XML в PostgreSQL.

Для начала пришлось поискать, где же его взять в наиболее удобном для обработки виде. Нашел!

Ставить какие-либо расширения на PostgreSQL не хотелось, поэтому ограничился прямым вызовом wget через COPY. Для этого сначала создаем временную таблицу:

DROP TABLE IF EXISTS tmp_tmp;
CREATE TEMP TABLE tmp_tmp (
  ID serial PRIMARY KEY,
  res text NOT NULL);

ID нам нужен исключительно для сохранения порядка строк, полученных от wget. Теперь мы вполне можем заполнить эту табличку и даже посмотреть на результат:

COPY tmp_tmp (res) FROM PROGRAM
  '/usr/bin/wget -qO - https://xmlcalendar.ru/data/ru/2026/calendar.xml'
  WITH (FORMAT text);
SELECT res FROM tmp_tmp ORDER BY ID;

Теперь нам нужно из полученных текстовых строк получить XML

SELECT string_agg(res,'' ORDER BY ID)::xml AS res
FROM tmp_tmp

Для проверки при помощи xmltable() распарсим заголовочную строку вида <calendar year="2026" lang="ru" date="2025.09.30" country="ru">, содержащую год, страну, для которой этот календарь, и дату его последнего изменения.

WITH CTE AS (
  SELECT string_agg(res,'' ORDER BY ID)::xml AS res
  FROM tmp_tmp ),
CheckYear AS (
  SELECT Y.for_year, Y.for_country, Y.create_date
  FROM CTE C
  CROSS JOIN xmltable('//calendar' PASSING C.res COLUMNS
    for_year smallint PATH '@year',
    for_country varchar PATH '@Country',
    create_date date PATH '@DaTe') Y
  WHERE Y.for_year=2026::smallint )
SELECT * FROM CheckYear

В дальнейшем я буду просто использовать имена общих табличных выражений, которые уже показал, не повторяя их код.

Теперь распарсим таблицу праздников. Она содержит только внутренний числовой идентификатор праздника и его полное наименование в строках вида <holiday id="6" title="День Победы"/>

WITH [...]
Holidays AS (
  SELECT H.id, H.title
  FROM CheckYear Y
  CROSS JOIN CTE C
  CROSS JOIN xmltable('//calendar/holidays/holiday' PASSING C.res COLUMNS
    id smallint PATH '@id',
    title varchar PATH '@title') H )
SELECT * FROM Holidays;

Затем распарсим основную часть, содержащую строки вида <day d="03.08" t="1" h="4"/> или <day d="04.29" t="1" f="04.27"/>. Тут требуются пояснения. Под тегом d скрывается дата в формате ММ.ДД. Тег t определяет тип записи: 1 - выходной день, 2 - рабочий и сокращенный (может быть использован для любого дня недели), 3 - рабочий день (суббота/воскресенье). Тег h является ссылкой на идентификатор праздника из предыдущего запроса. А тег f - дата с которой был перенесен выходной день тоже в формате ММ.ДД. При этом суббота и воскресенье считаются выходными, если нет тегов day с атрибутом t=2 и t=3 за этот день.

WITH [...]
SpecialDays AS (
  SELECT ('2026-'
    ||left(D.d,2)||'-'
    ||right(D.d,2))::date AS special_date,
  CASE WHEN D.t=1 THEN 'Holiday'
    WHEN D.t=2 THEN 'Shortened'
    WHEN D.t=3 THEN 'Working'
    ELSE NULL END AS day_type,
  ('2026-'
    ||left(D.f,2)||'-'
    ||right(D.f,2))::date AS from_date,
    H.title AS holiday_name
  FROM CheckYear Y
  CROSS JOIN CTE C
  CROSS JOIN xmltable('//calendar/days/day' PASSING C.res COLUMNS
    d varchar(5) PATH '@d',
    t smallint PATH '@t',
    h smallint PATH '@h',
    f varchar(5) PATH '@f') D
  LEFT JOIN Holidays H ON H.id=D.h )
SELECT * FROM SpecialDays;

Для наглядности я заменил числовые типы на краткое их строковое описание. Даты же из формата MM.ДД преобразовал в формат ISO ГГГГ-ММ-ДД, а затем уже в тип date.

Теперь осталось только сгенерировать календарь за год и для каждого дня указать количество рабочих часов для 40-часовой рабочей недели.

SELECT C.d::date AS pk_date,
  CASE WHEN S.day_type='Shortened' THEN 7
    WHEN S.day_type='Working' THEN 8
    WHEN S.day_type='Holiday' THEN 0
    WHEN extract(DOW FROM C.d) IN (0,6) THEN 0
    ELSE 8 END::smallint AS working_hours,
  S.from_date, S.holiday_name
FROM generate_series(('2026-01-01')::timestamp,
  ('2026-12-31')::timestamp,
   '1 day'::interval) C(d)
LEFT JOIN SpecialDays S ON S.special_date=C.d;

Сокращенные предпраздничные дни получили по 7 часов. Рабочие дни в выходные - 8. Праздники - 0. Воскресенье и суббота (в PostgreSQL нулевой и шестой дни недели соответственно) - 0. Ну а остальные дни считаются рабочими по 8 часов.

После всего этого осталось только создать функцию

CREATE OR REPLACE FUNCTION get_working_calendar(
  calendar_year smallint,
  calendar_lang varchar(2)='ru')
RETURNS TABLE (
  pk_date date,
  working_house smallint,
  from_date date,
  holiday_name varchar
) AS $function$
<<func>>
DECLARE
  sql_cmd varchar='COPY tmp_tmp (res) FROM PROGRAM $$'
    ||$$/usr/bin/wget -qO - https://xmlcalendar.ru/data/$$
    ||calendar_lang||$$/$$
    ||calendar_year::text
    ||$$/calendar.xml --no-check-certificate$$
    ||'$$ WITH (FORMAT text);';
BEGIN
DROP TABLE IF EXISTS tmp_tmp;
CREATE TEMP TABLE tmp_tmp (
  ID serial PRIMARY KEY,
  res text NOT NULL);
EXECUTE func.sql_cmd;

RETURN QUERY WITH CTE AS (
  SELECT string_agg(res,'' ORDER BY ID)::xml AS res
  FROM tmp_tmp ),
CheckYear AS (
  SELECT Y.for_year, Y.for_country, Y.create_date
  FROM CTE C
  CROSS JOIN xmltable('//calendar' PASSING C.res COLUMNS
    for_year smallint PATH '@year',
    for_country varchar PATH '@country,
    create_date date PATH '@date') Y
  WHERE Y.for_year=calendar_year ),
Holidays AS (
  SELECT H.id, H.title
  FROM CheckYear Y
  CROSS JOIN CTE C
  CROSS JOIN xmltable('//calendar/holidays/holiday'
    PASSING C.res COLUMNS
    id smallint PATH '@id',
    title varchar PATH '@title') H ),
SpecialDays AS (
  SELECT (calendar_year::text||'-'
    ||left(D.d,2)||'-'
    ||right(D.d,2))::date AS special_date,
  CASE WHEN D.t=1 THEN 'Holiday'
    WHEN D.t=2 THEN 'Shortened'
    WHEN D.t=3 THEN 'Working'
    ELSE NULL END AS day_type,
    (calendar_year::text||'-'
      ||left(D.f,2)||'-'
      ||right(D.f,2))::date AS from_date,
    H.title AS holiday_name
  FROM CheckYear Y
  CROSS JOIN CTE C
  CROSS JOIN xmltable('//calendar/days/day' PASSING C.res COLUMNS
    d varchar(5) PATH '@d',
    t smallint PATH '@t',
    h smallint PATH '@h',
    f varchar(5) PATH '@f') D
  LEFT JOIN Holidays H ON H.id=D.h )
SELECT C.d::date AS pk_date,
  CASE WHEN S.day_type='Shortened' THEN 7
    WHEN S.day_type='Working' THEN 8
    WHEN S.day_type='Holiday' THEN 0
    WHEN extract(DOW FROM C.d) IN (0,6) THEN 0
    ELSE 8 END::smallint AS working_hours,
  S.from_date, S.holiday_name
FROM CheckYear Y
CROSS JOIN generate_series((calendar_year::text||'-01-01')::timestamp,
    (calendar_year::text||'-12-31')::timestamp,
    '1 day'::interval) C(d)
LEFT JOIN SpecialDays S ON S.special_date=C.d;
END; $function$ LANGUAGE plpgsql;

И убедиться, что производственный календарь успешно загружается и парсится:

SELECT * FROM get_working_calendar(2024::smallint);

P.S. Забыл указать, что доступны производственные календари с 2015 года для России (ru) Белоруссии (by), Украины (ua), Казахстана (kz) и Узбекистана (uz)

P.P.S. Простите, если что, но после совершенно убогих постов про SQL, захотелось написать пост имеющий хоть ничтожную практическую ценность.

Показать полностью
SQL Postgresql Xml Текст Длиннопост
22
3
VelStyling
VelStyling
Серия SQL: знакомство

Неочевидные факты про MIN и MAX⁠⁠

1 месяц назад

Простые функции. Кажется, что они находят просто минимум и максимум. Но есть и особенность их использования для интерпретации результатов. Об этом далее.

Неочевидные факты про MIN и MAX

А пока подписывайся на мой канал На связи: SQL Там я публикую посты про особенности и нюансы SQL. Этот канал про то, как не бояться баз данных, понимать, что такое JOIN, GROUP BY и почему NULL ≠ 0. Его я веду с нуля подписчиков. Присоединяйся!

MIN и MAX — не только про числа

Они работают с любыми типами данных:

  • датами (MIN(date) даст самую раннюю дату),

  • строками (MAX(name) вернёт последнюю в алфавитном порядке),

  • булевыми значениями (MIN(bool) — false, MAX(bool) — true).

Иногда этим можно ловко воспользоваться — например, чтобы узнать, есть ли хоть один true:

SELECT MAX(is_active) FROM users;

Если вернёт true — значит, кто-то активен. Красиво и лаконично.

MIN и MAX — не только агрегатные, но и оконные функции

Можно получить минимум или максимум в рамках окна, не теряя детализацию:

SELECT

user_id,

date,

MAX(date) OVER (PARTITION BY user_id) AS last_activity

FROM logins;

Так можно легко вытащить, когда пользователь последний раз заходил — без группировки и без JOIN.

MIN/MAX и NULL

Они игнорируют NULL.
То есть если у тебя все значения NULL, то результат — NULL.
Это часто ломает аналитику, особенно при сравнении с COALESCE или при объединении данных.

SELECT MAX(COALESCE(score, 0)) -- вернёт 0, а не NULL

→ Иногда важно явно заменить NULL, чтобы не получить "пустой" результат.

MIN/MAX могут ускорить выборку

Если в таблице есть индекс по нужному полю —
MIN() и MAX() используют только крайний элемент индекса.
Это значит, что:

SELECT MAX(price) FROM products;

может пройтись не по миллиону строк, а просто взять последнее значение из B-tree индекса.
То есть — мгновенно.

Можно найти строку с минимальным/максимальным значением

Классическая боль аналитика: как вытащить не просто максимум, а всю строку, где он встретился.

💡 Один из лучших способов — оконная функция + фильтр:

SELECT *

FROM (

SELECT *,

ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn

FROM employees

) t

WHERE rn = 1;

→ Получаем сотрудника с максимальной зарплатой.
Без подзапросов, без JOIN, без боли.

Неочевидный кейс: поиск экстремумов в группах

SELECT department, MIN(salary), MAX(salary)

FROM employees

GROUP BY department;

Классика, но важно:
разница между MAX и MIN = разброс значений, полезный показатель в аналитике (например, зарплат).

💬 Если хочешь больше таких разборов с реальными кейсами SQL без воды — подписывайся на мой Telegram 👉На связи: SQL
Там я рассказываю про SQL так, чтобы стало интересно даже тем, кто раньше его ненавидел 😄

Показать полностью 1
[моё] SQL Аналитика Аналитик База данных Microsoft Excel Анализ данных Min Саморазвитие Эмоциональное выгорание Длиннопост
4
15
Slava.Rozhnev
Slava.Rozhnev
Серия SQLize.online

SQL-кодеры, приготовиться! Онлайн-песочница sqlize.online получила большие обновления (и свежую Oracle 26ai)⁠⁠

1 месяц назад

Привет, Пикабу! На связи Слава Рожнев, который все ещё делает sqlize.online — ту самую удобную онлайн-песочницу, где можно быстро проверить SQL-запрос, не устанавливая тяжеловесные СУБД.

Я тут немного поколдовали над кодом и выкатил пару жирных обновлений, которые сильно упростят жизнь всем, кто работает с базами данных или только учится.

💾 Больше не нужно копировать в блокнот: Сохраняем код!

Раньше было как? Написал ты, например, сложный CUBE или крутую оконную функцию, чтобы решить задачу, получил результат, закрыл вкладку — и всё, код улетел в Лету.

Теперь это в прошлом! Я добавил регистрацию на платформе. и возможность для всех зарегистрированных пользователей сохранять свои примеры кода!

Это прямо must-have, если вы:

* Решаете задачки и хотите вернуться к ним позже.

* Собираете личные «шпаргалки» для работы с разными диалектами SQL.

* Просто не хотите потерять гениальный запрос, который родился в 3 часа ночи.

Теперь ваши наработки хранятся в личном кабинете. Пользуйтесь на здоровье!

🚀 Oracle 26ai: Выходим на новый уровень

А вот это вишенка на торте для фанатов энтерпрайзных баз данных: мы обновили версию Oracle до самой последней — 26ai!

Да-да, с прицелом на искусственный интеллект. Теперь вы можете тестировать свои запросы на самой свежей и навороченной версии, которая включает массу новых фич, улучшенную производительность и, конечно, все те возможности, которые Oracle предлагает в области работы с ИИ и аналитикой.

Что это значит для вас:

* Вы работаете с самым актуальным инструментарием.

* Можно заранее проверить, как будут работать ваши запросы в самой современной продакшн-среде.

* Прощайте, устаревшие синтаксические конструкции, привет, новые возможности!

Итого:

* Регистрация: Готово!

* Сохранение кода: Готово!

* Oracle 26ai: Готово!

Заходите, регистрируйтесь, сохраняйте свои мега-запросы и ломайте нашу новую Oracle 26ai (в пределах разумного, конечно). Жду ваших багрепортов и предложений в комментариях.

Всем удачи в кодинге и да пребудет с вами долгожданный QUALIFY!

Наш девиз: «Надо тестить? Заходи, инсталляция не нужна!»

Показать полностью
[моё] Программирование IT Обучение SQL Oracle База данных Песочница Текст
3
4
VelStyling
VelStyling
Серия SQL: знакомство

AVG. Почему "среднее" не всегда среднее⁠⁠

1 месяц назад

Когда мы видим AVG, кажется, всё просто:

Возьми все значения и найди среднее арифметическое.

Но на практике AVG часто ведёт себя не так, как ты ожидаешь — и это причина десятков аналитических факапов в отчётах.

AVG. Почему &quot;среднее&quot; не всегда среднее

А пока подписывайся на мой каналНа связи: SQL Там я публикую посты про особенности и нюансы SQL. Этот канал про то, как не бояться баз данных, понимать, что такое JOIN, GROUP BY и почему NULL ≠ 0. Его я веду с нуля подписчиков. Присоединяйся!

Что делает AVG()?

AVG() - агрегатная функция. Она считает среднее значение по всем строкам, которые попали в выборку после фильтрации WHERE

SELECT AVG(column_name)

FROM table_name

WHERE condition;

Пример:

| id | salary |
| -- | ------ |
| 1 | 1000 |
| 2 | 2000 |
| 3 | NULL |
| 4 | 3000 |

SELECT AVG(salary) FROM employees;

Результат → 2000

❗ Почему не (1000 + 2000 + 0 + 3000) / 4 = 1500?

Потому что AVG игнорирует NULL.
Он считает (1000 + 2000 + 3000) / 3.

Если тебе нужно учесть “отсутствие зарплаты” как ноль —
надо явно это сказать базе:

SELECT AVG(COALESCE(salary, 0)) FROM employees;

Где используется AVG

AVG() — базовый инструмент в аналитике:

  • 📈 средний чек (AVG(order_amount))

  • 💰 средняя зарплата по отделу

  • 🕒 среднее время выполнения заказа

  • ⭐ средний рейтинг продукта

Но это только верхушка айсберга.
Ниже — интересные кейсы, где AVG используется неочевидно, но мощно 👇

Обычный AVG считает всё одинаково,
но в реальном мире “вес” данных может быть разный.

Пример — средняя оценка курса:

| user_id | rating | reviews |
| ------- | ------ | ------- |
| 1 | 5 | 1 |
| 2 | 4 | 20 |

Если ты просто возьмёшь AVG(rating) → 4.5
Но по факту второй пользователь оставил 20 отзывов, его мнение должно весить больше:

SELECT SUM(rating * reviews) / SUM(reviews) AS weighted_avg

FROM ratings;

Вот это уже взвешенное среднее, и результат будет ближе к 4.

AVG не коммутативен в агрегациях

AVG(AVG(...)) ≠ AVG(...)

Пример:

| group | value |

| ----- | ----- |

| A | 10 |

| A | 20 |

| B | 100 |

| B | 100 |

| B | 100 |

SELECT AVG(avg_val) FROM (

SELECT group, AVG(value) AS avg_val

FROM t GROUP BY group

) s;

Результат будет → 57.5
А реальное среднее по всей таблице = 86.

Почему?
Потому что при втором AVG каждая группа имеет одинаковый “вес”,
а не количество строк. Это типичный аналитический капкан.

AVG в окнах (window functions)

AVG() можно использовать по “скользящему окну”, чтобы считать динамику:

SELECT

date,

AVG(price) OVER (ORDER BY date ROWS 6 PRECEDING) AS moving_avg_7d

FROM stock_prices;

👉 Это 7-дневное скользящее среднее — классика анализа временных рядов, трейдинга и предсказания трендов.

Среднее как критерий “нормальности”

В аналитике AVG часто используют вместе со STDDEV:

STDDEV (Standard Deviation) — стандартное отклонение (среднеквадратичное отклонение). Это статистическая мера разброса данных относительно их среднего значения в определённом периоде.

SELECT *

FROM purchases

WHERE amount > AVG(amount) + 3 * STDDEV(amount);

Так находят аномально большие значения — подозрительные платежи, мошеннические операции и т.д.

AVG по датам — это тоже работает

Мало кто знает, что AVG() можно применять даже к датам:

SELECT AVG(order_date)::date FROM orders;

PostgreSQL переведёт даты во внутренние числа и вычислит “среднюю дату” —
по сути, середину временного диапазона.
Это удобно, если хочешь понять, когда чаще всего происходили события.

AVG и производительность

AVG() всегда вычисляется через SUM и COUNT,
поэтому если ты делаешь:

SELECT COUNT(*), SUM(amount), AVG(amount)

— оптимизатор посчитает всё за один проход по данным.
Но если AVG в отдельном запросе — будет второй проход.
Мелочь, а при миллионах строк чувствуется.

Мой канал На связи: SQL ждет тебя, если ты тоже хочешь познакомиться с базовым языком для аналитики данных.

Подписывайся!

Показать полностью 1
[моё] Аналитик Аналитика Отчетность Microsoft Excel SQL База данных Длиннопост
0
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии