Налейте аналитику
918 subscribers
43 photos
2 files
33 links
Мысли вслух лида аналитики ЛитРес, уроки по SQL/Python для новичков и не только, рассуждения о том, как делать надо и главное - как не надо, что должен уметь начинающий аналитик и чем дата-саентист отличается от дата-инженера

karaulovandrey@yandex.ru
Download Telegram
Что еще важно отметить. COUNT(*) посчитает все строки в таблице с учетом заданных условий. При использовании простых запросов к одной таблице без JOIN-ов COUNT(*) можно использовать, не задумываясь. Но если запрос сложный, происходит объединение и работа с несколькими таблицами, есть риск получить задвоенные/затроенные/заNенные цифры в ответе. Почему это может происходить коснемся в задаче, где появится первый JOIN.

Поэтому для надежности вычислений COUNT(*) можно заменить на COUNT(DISTINCT уникальный ключ), немного преобразовав запрос:
SELECT

COUNT(DISTINCT id) AS count

FROM Trip

WHERE

plane = 'TU-134'
#дайджест

В последнее время все посты выходили по теме разбора простеньких задач из тренажера SQL (уже скоро начнутся задачи поинтереснее), поэтому предыдущие посты немного затерялись, возможно, часть аудитории о них и не знает )

Поэтому небольшой дайджест тем, которые уже успели выйти на канале:

1. Что должен уметь аналитик данных?

2. О курсах и самообразовании

3. Как начать работать в Питоне тем, кто никогда с ним не сталкивался?

4. Какие бывают аналитики? Классификация

5. Зарплатные вилки аналитиков

6. Ключевой навык аналитика (и не только)

7. О джойнах и INNER/LEFT JOIN в частности

8. Краткий обзор плюсов и минусов PowerBI и Tableau

9. Про АБ-тесты
Поговорим о JOIN-ах

Оператор JOIN в SQL используется для объединения таблиц и получения результатов запроса из нескольких таблиц разом. Синтаксис запроса с участием JOIN-а двух таблиц, а также различные виды JOIN-ов можно увидеть на схеме ниже (не эта с кучей кружочков, это так, шутки ради)
Что надо помнить, изучая подобное Эйлеровское представление оператора JOIN?

1. Во-первых, учить все виды JOIN-ов, может, необходимо для экзамена в университете, но для решения реальных задач не нужно. 95% задач на практике решается с использованием INNER JOIN и LEFT JOIN, и уж поверьте, намного лучше досконально разобраться для начала только в этих типах соединений, чем по верхам изучить все, в т.ч. CROSS JOIN (в схеме не упомянут) или тот же FULL OUTER JOIN, а запросы писать попеременно с использованием то LEFT, то RIGHT JOIN-ов. Я, например, когда вижу запросы с RIGHT JOIN-ами, чувствую умственное напряжение сродни тому, которое испытываешь перед пешеходным переходом в Британии или на Кипре: 2-3 секунды уходит на то, чтобы переформатировать свой мозг под необычное движение не в ту сторону )

2. Во-вторых, надо помнить степень абстракции, с которой кружочки отражают действительность при объединении таблиц. Ошибки при работе кроются в дублировании данных при JOIN-ах, про которое некоторые забывают
Пусть есть табличка с книгами и их скачиваниями (books) и табличка с авторами этих книг (authors). На что стоит обратить внимание:

1. В таблице books есть книга "Сказки народов мира", у которой нет соответствия в таблице authors

2. У книги "Чудо-пилюли" из таблицы books есть 2 соответствия в таблице authors.

Результат JOIN-а нескольких таблиц - это таблица. И для избежания ошибок в запросах необходимо научиться мысленно визуализировать эту таблицу и понимать ее состав полей и особенности.

Держим в голове 2 пункта выше. Так как использован INNER JOIN, в результирующей таблице будут только те строки, которые есть в обеих таблицах, к которым написан запрос. Соответственно, книги "Сказки народов мира" в результате не будет. А книга "Чудо-пилюли" займет в результате 2 строки, т.к. соответствие в исходных таблицах для этой книги один-к-двум.
Напоследок приложу результат того же запроса, только с использованием не INNER JOIN, а LEFT JOIN.

Как видно, изменилось только одно: книга, у которой не было соответствия в таблице authors, теперь есть в результате, а ее автор заполнился на пустое значение NULL.
Налейте аналитику pinned «#дайджест В последнее время все посты выходили по теме разбора простеньких задач из тренажера SQL (уже скоро начнутся задачи поинтереснее), поэтому предыдущие посты немного затерялись, возможно, часть аудитории о них и не знает ) Поэтому небольшой дайджест…»
Разбор задачи SQL №6

#SQL_trainer5

В прошлый раз я затронул тему JOIN-ов. В шестой задаче тренажера нам впервые потребуется объединять таблицы.

Задача - вывести названия (name) компаний, которые совершали полет на Boeing.
Предполагаю, что если одна и та же компания летала на Boeing несколько раз, нам достаточно вывести ее название единожды. Другими словами, требуется список из уникальных имен компаний, значит, в запросе будет фигурировать DISTINCT:

SELECT DISTINCT

c.name

FROM Trip AS t

JOIN Company AS c ON t.company = c.id

WHERE

t.plane = 'Boeing'
Замечу, что в запросе используются так называемые Элиасы (Alias), которые назначаются таблицам (а также полям, вложенным запросам и т.д.) с помощью конструкции table_name AS alias и позволяют задать объекту новое временное имя в рамках запроса (вместо Trip.company можно теперь писать t.company). В большинстве случаев Элиасы повышают читаемость запросов и/или интерпретируемость названий объектов.

Также стоит отметить, что в SQL JOIN эквивалентен INNER JOIN и зачастую часть INNER опускается
Разбор задачи SQL №10

#SQL_trainer6

В прошлой статье мы разобрали решение 6 задачи. Сейчас же перепрыгнем сразу на десятую, т.к. в 7, 8, и 9 нет ничего принципиально интересного или нового (разве что, в восьмой используется оператор для расчета разницы между двумя datetime-переменными TIMEDIFF(t.time_in, t.time_out) AS flight_time).

Задача - Вывести вылеты, совершенные с 10 ч. по 14 ч. 1 января 1900 г.
Задачка, казалось бы, пустяковая. Но хочу остановиться на одном моменте. По опыту проведения тестовых заданий, 7 из 10 человек в подобной задаче напишут запрос подобного вида:

SELECT *

FROM Trip AS t

WHERE

t.time_out BETWEEN '1900-01-01 10:00' AND '1900-01-01 14:00'


(Спойлер - это в том числе является правильным ответом). И у меня всегда возникает вопрос, зачем использовать BETWEEN? В задаче, где речь пойдет не о датах, а о числовых значениях (вывести, например, всех людей с кол-вом заказов от 5 до 10), те же самые люди и не вспомнят о BETWEEN, а обойдутся больше/меньше/больше или равно/меньше или равно.
Чем неудобен BETWEEN? Собственно, только тем, что границы интервала по умолчанию включены в результат. И это дает куда меньшую вариативность либо необходимость дополнительных условий. Куда проще использовать знакомые со школы "> < >= <=".

Хочешь, чтобы границы дат попадали? t.time_out >='1900-01-01 10:00' AND t.time_out <= '1900-01-01 14:00' (эквивалентно BETWEEN)

Наоборот, не попадали? t.time_out >'1900-01-01 10:00' AND t.time_out < '1900-01-01 14:00'
Вот пример реального запроса с BETWEEN. Обратите внимание, что '2021-07-22 00:00:00' попадает в условие BETWEEN '2021-07-21' AND '2021-07-22'. Если это не учитывать, то можно с легкостью посчитать лишнюю транзакцию или еще что-то, что не подразумевалось автором запроса.
Поэтому я бы запрос к задаче №10 сформировал такой:

SELECT *

FROM Trip AS t

WHERE t.time_out >='1900-01-01 10:00'

AND t.time_out <='1900-01-01 14:00'
Разбор задачи SQL №13

#SQL_trainer7

В прошлый раз разбиралась десятая задача. В этот раз начнем разбирать тринадцатую, в которой познакомимся c элементом запроса HAVING. На мой взгляд, это первая задача, которая требует чуточку сообразительности.

Задача - Вывести имена людей, у которых есть полный тёзка среди пассажиров.
На самом деле, сообразительность нужна только для того, чтобы переформулировать постановку "Вывести имена людей, у которых есть полный тёзка среди пассажиров" в более понятную "Вывести name из таблицы Passenger, встречающиеся более 1 раза".

Для начала поймем, как построить запрос с группировкой по имени пассажиров (name) и кол-вом таких имен в таблице. Это не очень сложно:

SELECT

name, COUNT(*)

FROM Passenger

GROUP BY name

ORDER BY COUNT(*) DESC
Видим, что имена всех пассажиров, кроме одного имени, встречаются по 1 разу. Собственно, именно это имя нам и нужно - осталось убрать из ответа всех остальных. Для этого нам как раз понадобится HAVING. HAVING - команда, аналогичная WHERE, но с той разницей, что WHERE идет в запросе до группировки и накладывает условия на поля в таблице, а HAVING идет после группировки GROUP BY и накладывает условия на результат этой группировки.