← Все курсы · Курс SQL · Все руководства
Основы SQL, от начала до конца
К концу этой страницы вы сможете сказать вслух и своими словами, что делает каждая основная часть SQL. Что на самом деле представляют собой таблица и строка. Шесть предложений и порядок, в котором они на самом деле выполняются, а не тот порядок, в котором вы их вводите. NULLи почему это нарушает сравнения. Фильтрация, агрегирование, GROUP BY и HAVING. Присоединяется. CASE. Подзапросы, CTE и оконные функции. Ключи и индексы. Этот список — это большая часть того, что от вас потребуют на работе аналитика, на собеседовании и на первом реальном наборе данных.
Вот что на самом деле с этим делать. Пройдите один раз от начала до конца, не останавливаясь, просто для формы. Затем вернитесь к листу для поиска внизу, закройте правый столбец и попытайтесь произнести каждый ответ, прежде чем прочитать его. На втором этапе происходит обучение, и на дальнейших этапах есть измеренные доказательства этого.
Краткая версия: SQL — это одно предложение, состоящее из шести частей, каждая часть отвечает на отдельный вопрос о ваших строках. Узнайте, что делает каждая часть и где она работает, а остальное — словарный запас.
Одна идея в большей степени определяет ваш опыт работы с SQL, чем любая другая, поэтому она дает представление о картине. Вы пишете запрос в одном порядке. База данных запускает его в другом порядке. Почти каждая сбивающая с толку ошибка SQL является этим пробелом.
- Таблицы, строки и одно слово, которое предотвращает большинство ошибок
- Шесть пунктов и порядок их выполнения
- Фильтрация и что с ней делает NULL
- Агрегация, ГРУППИРОВКА ПО и ИМЕЮЩАЯ
- Объединение двух таблиц
- Формирование вывода: DISTINCT, ORDER BY, CASE, псевдонимы.
- Подзапросы, CTE и оконные функции
- Ключи, индексы и что означает реляционный характер
- Как это изучить, чтобы это прижилось
- Все на одном экране
1. Таблицы, строки и одно слово, которое предотвращает большинство ошибок.
Перед пояснением: две таблицы содержат по 500 строк. Означает ли это, что они содержат одинаковое количество информации об одних и тех же вещах?
A Таблица представляет собой сетку. Столбцы — это поля, и каждое значение в столбце — это одно и то же. Строки — это записи. А база данных представляет собой набор таблиц, которые знают друг о друге.
Теперь слово, которое предотвращает большинство ошибок SQL: grain. Уровень детализации таблицы — это то, что означает одна строка. Скажите это как предложение, начинающееся с «одна строка на».
- Таблица клиентов содержит одну строку на каждого клиента.
- Таблица заказов содержит одну строку на заказ.
- Таблица строк заказа содержит одну строку на каждый продукт в заказе.
Все эти три таблицы могут иметь по 500 строк и означать совершенно разные вещи. Уровень детализации — это ответ на вопрос «что я считаю», и каждый счет, сумма и среднее значение, которые вы пишете, — это ответ на какое-то уровень детализации. Если число оказывается неправильным, оно обычно оказывается верным в той степени, которую вы не предполагали.
Еще одна вещь, которую нужно знать о таблице, прежде чем запрашивать ее, — это ее Типы данных. В широком смысле: целые числа, десятичные числа, текст, даты и логические значения. Виды не являются украшением. Дата, сохраненная в виде текста, будет отсортирована в алфавитном порядке, поэтому первое декабря будет предшествовать второму января. Число, сохраненное в виде текста, не будет корректно сравниваться или складываться. Если что-то очевидное отказывается работать, сначала проверьте тип.
2. Шесть пунктов и порядок их выполнения
Перед пояснением: вы называете столбец revenue в твоем SELECT, затем попробуйте отфильтровать revenue в твоем WHERE, а в базе данных указано, что такого столбца нет. Это прямо здесь, на строке выше. Почему база данных его не видит?
Вот запрос, использующий каждое предложение. В этом вся суть SQL, а все остальное — его вариации.
SELECT region, COUNT(*) AS orders
FROM orders
WHERE order_date >= '2026-01-01'
GROUP BY region
HAVING COUNT(*) > 100
ORDER BY orders DESC
LIMIT 10;
Прочтите в порядке ввода: покажите мне эти вещи, отсюда, где это правда, сгруппированы вот так, оставьте только такие группы, отсортированы вот так и остановитесь после десяти.
Но база данных не запускает его в таком порядке. Он работает FROM, затем WHERE, затем GROUP BY, затем HAVING, затем SELECT, затем ORDER BY, затем LIMIT. Именно такой порядок показан на картинке выше, и он объясняет три вещи, которые люди иначе запоминают как произвольные правила.
Первое – это ваш вопрос. WHERE бежит раньше SELECT, так что на данный момент WHERE оценивается псевдоним revenue еще не существует. Вот почему вам придется повторить все выражение в WHEREили оберните запрос в другой.
Второй WHERE против HAVING, который является самым часто задаваемым вопросом на собеседовании по SQL после присоединения. WHERE запускается перед группировкой, поэтому фильтрует отдельные строки. HAVING запускается после группировки, поэтому он фильтрует группы и является единственным, кто может видеть агрегат типа COUNT(*). «Заказы на сумму более 500 долларов» — это WHERE. «Регионы с более чем 100 заказами» — это HAVING.
Третий заключается в том, что ORDER BY бежит за SELECT, вот почему это может используйте свой псевдоним. ORDER BY orders DESC работает в приведенном выше запросе с именем, которое WHERE не мог видеть. Тот же запрос, тот же псевдоним, другой ответ исключительно из-за того, когда выполняется каждое предложение.
Прежде чем читать дальше, скажите это вслух: почему можно ORDER BY используйте псевдоним, который WHERE не может?
3. Фильтрация и что с ней делает NULL
Перед пояснением: в таблице 100 строк. Вы запускаете один фильтр и получаете 60 строк, затем запускаете противоположный фильтр и получаете 30. Где остальные 10?
WHERE сохраняет строки, которые делают условие истинным. Строительные блоки небольшие.
| Оператор | Что он делает |
|---|---|
= <> < > <= >= | Сравните одно значение с другим |
AND OR NOT | Объедините условия. AND применяется до OR, поэтому используйте скобки, когда смешиваете их. |
IN (a, b, c) | Соответствует любому значению в списке. короче, чем цепочка OR. |
BETWEEN x AND y | Диапазон, и оба конца включены |
LIKE 'north%' | Текстовый узор. % означает любую серию символов, _ означает ровно один. |
IS NULL / IS NOT NULL | Единственный правильный способ проверить пропущенное значение |
Это подводит нас к ответу на предварительный вопрос. NULL не означает ноль и не означает пустой текст. Это значит неизвестно. И сравнение с неизвестным не оказывается ложным, оно возвращает неизвестное, что является третьим состоянием. Строка, значение которой неизвестно, не проходит оба region = 'North' и region <> 'North', потому что SQL не может сказать, что ни одно из них истинно. Этих десяти строк нет ни в одном результате.
Вот почему = NULL никогда не работает и IS NULL это отдельная часть синтаксиса. Вот почему NOT IN против списка, содержащего NULL вообще ничего не возвращает, что в первый раз становится действительно неприятным днем.
Повседневная привычка, которая вас спасает: всякий раз, когда вы пишете фильтр, исключающий что-то, спрашивайте, что происходит со строками, где столбец неизвестен, и решайте специально. Часто вы хотите WHERE region <> 'North' OR region IS NULL.
4. Агрегация, группировка и наличие
Перед объяснением: COUNT(*) и COUNT(customer_id) в одной и той же таблице могут возвращаться разные числа. В чем разница между тем, что задают эти два вопроса?
Ан агрегатная функция принимает много строк и возвращает одно значение. Есть пять, которые вы будете использовать постоянно: COUNT, SUM, AVG, MIN, MAX.
GROUP BY решает, что означает «много строк». Без него агрегат сворачивает всю таблицу в одну строку. С GROUP BY region, он сжимается до одной строки на регион, и внутри каждого из них вычисляется агрегат. Это та же идея, что и уровень детализации вида в Tableau, и если вы сталкивались с этим, то это точно такая же механика в другой одежде. Прохождение этого есть в Руководство по концепциям Tableau.
Следующее правило: каждый столбец в вашем SELECT должно быть либо в GROUP BY или быть обернутым в совокупность. Третьего варианта нет, потому что нет разумного ответа на вопрос «дайте мне имя клиента для этой группы из 400 клиентов».
Теперь на счет три, это и есть предварительный вопрос.
| Написано как | имеет значение |
|---|---|
COUNT(*) | Ряды. Каждый ряд, включая полные NULL. |
COUNT(customer_id) | Строки, в которых нет этого столбца NULL. Отсутствующие значения пропускаются. |
COUNT(DISTINCT customer_id) | Сколько разных клиентов, независимо от того, сколько строк каждый занимает. |
Это три совершенно разных вопроса: сколько строк, сколько строк содержат это и сколько различных вещей. Разрыв между первой и третьей — это самый быстрый способ обнаружить повторяющиеся строки, поэтому он возвращается в руководство по соединениям.
AVG Пропускает NULL тоже, что имеет большее значение, чем кажется. Если 40 из 100 строк не имеют значения, AVG делится на 60, а не на 100. Если пропущенное значение действительно означает ноль, сначала замените его на COALESCE(column, 0), который возвращает первый объект в своем списке, который не является NULL.
Теперь представьте свои собственные данные. Если вы сгруппировали их по наиболее очевидному столбцу категории и подсчитали строки, какая группа будет самой большой, и будет ли это открытием или просто отражением того, как собирались данные?
5. Объединение двух таблиц
Перед пояснением: вы присоединяете таблицу клиентов к таблице заказов. Ни одна таблица не изменилась. Почему в результате может быть больше строк, чем в обеих?
A Объединение таблиц (JOIN) объединяет две таблицы путем сопоставления строк по общему значению, называемому ключом. Механика — это одно предложение, и его стоит придерживаться: для каждой строки слева база данных находит каждую строку справа, ключ которой совпадает, и записывает по одной выходной строке на каждую пару.
Это предложение отвечает на вопрос. Покупатель с тремя заказами создает три пары, то есть три выходных ряда, в каждой из которых повторяются сведения о покупателе. Умножьте это на таблицу, и результат будет больше, чем любой входной сигнал.
В этом же предложении объясняется и противоположная неудача. Покупатель, у которого нет заказов, не создает пар, поэтому не имеет выходных строк, и они исчезают из результата без ошибок и предупреждений.
Типы, кратко. INNER JOIN сохраняет только совпадающие пары. LEFT JOIN сохраняет каждую строку из левой таблицы, заполняя правую часть NULL где ничего не совпало. RIGHT JOIN делает то же самое наоборот. FULL OUTER JOIN сохраняет несовпадающие строки с обеих сторон. CROSS JOIN сочетает все со всем и почти никогда не бывает тем, что вы хотите случайно.
В соединениях возникает наибольшая доля реальных ошибок аналитиков, и оба режима сбоя невидимы в тексте запроса и очевидны при подсчете строк. Это целое руководство: как объединить две таблицы, не теряя и не удваивая строки работает с обоими на 41 миллионе реальных строк, с двумя счетчиками, которые перехватывают каждую из них.
6. Формирование вывода: DISTINCT, ORDER BY, CASE, псевдонимы.
Перед пояснением: в вашем результате один и тот же клиент указан девять раз. Является DISTINCT исправление или это способ скрыть вопрос, который вам следует задать?
DISTINCT удаляет повторяющиеся строки из результата. Это полезно для настоящего вопроса, например «какие регионы указаны в этой таблице». Это опасно как рефлекс, поскольку повторяющиеся строки обычно означают, что соединение умножило ваши данные, и удаление их вручную скрывает это, а не исправляет. Сначала спросите, откуда взялись дубликаты, а затем принимайте решение.
ORDER BY сорта. По возрастанию по умолчанию, DESC по убыванию, и вы можете сортировать по нескольким столбцам в порядке приоритета. LIMIT занимает первые н строк и является вашим лучшим другом на столе, который вы никогда раньше не открывали, потому что SELECT * FROM big_table LIMIT 10 покажет вам, с чем вы имеете дело, за секунду.
псевдонимы переименовывать вещи. AS avg_hours называет выходной столбец и FROM customers AS c называет таблицу, чтобы вы могли писать c.name. Двум объединенным таблицам почти всегда нужны эти псевдонимы, поскольку обе могут содержать столбец с одинаковым именем. Вся привычка заключена в Псевдонимы SQL и чтение запроса вслух.
CASE — это оператор «если-то» SQL, который преобразует столбец в категории.
SELECT name,
CASE WHEN tenure_months < 12 THEN 'First year'
WHEN tenure_months < 36 THEN 'Established'
ELSE 'Loyal'
END AS segment
FROM customers;
Он читает сверху вниз и останавливается на первом совпадении, поэтому для каждого из приведенных выше диапазонов не требуется верхняя граница. Все, что не соответствует, попадает в ELSE, и без ELSE это становится NULL. CASE также работает внутри агрегата, то есть подсчета подмножества в том же запросе: SUM(CASE WHEN churned = 1 THEN 1 ELSE 0 END).
7. Подзапросы, CTE и оконные функции
Прежде чем объяснить: вам нужно сравнить расходы каждого клиента со средними показателями по его региону. Для этого нужны две разные группы в одном результате. Как один запрос может иметь два зерна одновременно?
Три инструмента, и это шаг от написания запросов к их структурированию.
A подзапрос это запрос внутри другого запроса. Он может сидеть в FROM, где он действует как временная таблица, или в WHERE, где он предоставляет значение или список для сравнения.
A CTE, обычное табличное выражение, представляет собой ту же идею, написанную так, чтобы человек мог ее прочитать. Вы заранее называете результат с помощью WITH, затем используйте это имя ниже.
WITH regional AS (
SELECT region, AVG(spend) AS region_avg
FROM customers
GROUP BY region
)
SELECT c.name, c.spend, r.region_avg
FROM customers AS c
JOIN regional AS r ON c.region = r.region;
Это ответ на предварительный вопрос, сделанный явным образом. Вычислите ответ на уровне региона один раз, присвойте ему имя, а затем соедините его со строками на уровне клиента. Чтение сверху вниз происходит в том же порядке, в котором выполняется работа, поэтому CTE стоит использовать, даже если подойдет вложенный подзапрос. Запрос, которому может следовать кто-то другой, — это запрос, которому кто-то другой будет доверять.
A оконная функция получает тот же результат без соединения. Он выполняет вычисления по набору связанных строк, сохраняя при этом каждую строку.
SELECT name, spend,
AVG(spend) OVER (PARTITION BY region) AS region_avg
FROM customers;
В этом вся идея: OVER говорит: «Посмотрите в окно рядов», и PARTITION BY говорит, какие строки принадлежат одному и тому же окну. Обычный GROUP BY сворачивает ваши строки. Оконная функция выполняет ту же самую математику и сохраняет их. Другие распространенные из них: ROW_NUMBER, RANK и DENSE_RANK для нумерации строк внутри каждой группы и LAG и LEAD для достижения предыдущей или следующей строки, именно так вы рассчитываете ежемесячные изменения.
8. Ключи, индексы и что означает реляционный характер
Прежде чем объяснить: почему адрес одного и того же клиента хранится в одной таблице, а не повторяется в каждом его заказе?
A первичный ключ столбец, который однозначно идентифицирует строку. Один идентификатор клиента, один клиент, никогда не повторяется, никогда NULL. А внешний ключ тот же самый идентификатор появляется в другой таблице, чтобы указать назад, поэтому заказ содержит идентификатор клиента того, кто его разместил.
Эта пара и есть полный ответ на заданный вопрос. Адрес живет в одном месте, поэтому его изменение меняет его повсюду, и две копии не могут не согласиться. Разделение данных на таблицы, которые ссылаются друг на друга по ключу, называется нормализацией, и на практике именно это означает реляционность.
Ан индекс — это структура поиска, которую база данных хранит в столбце, поэтому ей не нужно читать каждую строку, чтобы найти значение. Стоимость - мало места и чуть медленнее пишет. Выгода для большой таблицы огромна: сопоставление 125 855 строк с 41 миллионом позволяет перейти от полного сканирования к поиску. Индексируйте столбцы, к которым вы присоединяетесь, и фильтруйте их. руководство по работе с большими наборами данных охватывает остальную часть работы в этом размере.
И последнее, что стоит знать, прежде чем вы встретитесь с ним. SQL является стандартом, но каждая база данных расширяет его. Функции даты, строковые функции и способы ограничения строк различаются в PostgreSQL, MySQL, SQLite, SQL Server и БигЗапрос. Суть этого руководства везде одинакова. Когда функция не существует, вы обычно говорите на другом диалекте, а не ошибаетесь.
Как это изучить, чтобы это прижилось
Повторное чтение этой страницы будет напоминать обучение, но в большинстве случаев таковым не будет. Три открытия меняют ценность часа обучения, и все три не требуют больших усилий.
Во-первых, при извлечении чего-либо из памяти это сохраняется лучше, чем при просмотре. Студенты, которые читали отрывок один раз, а затем проходили тесты на запоминание, неделю спустя вспоминали гораздо больше, чем студенты, которые читали один и тот же отрывок четыре раза, хотя те, кто перечитывал, чувствовали себя более уверенно (Краснее & выбирать карпа, 2006, Психологическая наука, 17(3), 249–255). Применимо здесь: закройте правую колонку листа для поиска ниже и произнесите каждый ответ, прежде чем смотреть. Борьба — это механизм, а не признак того, что вы делаете это плохо.
Второе — это интервал. То же самое общее время исследования, распределенное по дням, а не упакованное в один присест, обеспечивает существенно лучшее запоминание, и эффект сохраняется в сотнях экспериментов (Сепеда, Пашлер, Вул, Викстед & Рорер, 2006, Психологический вестник, 132(3), 354–380). Три двадцатиминутных прохода за три дня превосходят один час сегодня вечером.
В-третьих, почему это руководство постоянно просит вас говорить что-то вслух. Учащиеся, которые объясняют себе проработанный пример по ходу дела, понимают его значительно лучше и лучше переносят его на новые задачи, чем учащиеся, которые читают тот же пример, не объясняя его (Чи, Басок, Льюис, Рейманн & Глейзер, 1989, Когнитивная наука, 13(2), 145–182). SQL — это то место, где это окупается больше всего, потому что ошибка почти никогда не бывает в ключевом слове. Это то, что, по вашему мнению, означает одна строка.
Если у вас под рукой есть бумага и свободные пять минут, стоит сделать один рисунок, и он не является обязательным. Нарисуйте по памяти два столбца с рисунка вверху, вводя порядок слева и порядок выполнения справа, и соедините их. Эта концепция имеет самые последующие последствия, и ее извлечение из памяти — это одновременно и попытка восстановления, и проверка того, действительно ли она у вас есть.
Все на одном экране
Это лист поиска. Закройте правую колонку, проработайте левую и произнесите каждый ответ вслух, прежде чем проверять его.
| концепция | Что он делает |
|---|---|
| Grain | Что означает одна строка. Скажите это как «одна строка на что-то». |
| Порядок выполнения | ОТКУДА, ГДЕ, ГРУППИРУЙТЕ, ИМЕЕТ, ВЫБИРАЙТЕ, Упорядочивайте, LIMIT. |
| Почему WHERE нельзя использовать псевдоним | WHERE выполняется перед SELECT, поэтому псевдоним еще не существует. |
| Почему ORDER BY может | ORDER BY выполняется после SELECT. |
| WHERE | Фильтрует отдельные строки перед группировкой. |
| HAVING | Фильтрует группы после группировки. Единственный, который видит агрегат. |
| NULL | Неизвестно, не ноль и не пусто. Сравнения с ним не являются ни истинными, ни ложными. |
| IS NULL | Единственный правильный тест на пропущенное значение. = NULL никогда не работает. |
| COALESCE | Возвращает первое значение в своем списке, отличное от NULL. |
| СЧИТАТЬ(*) | Подсчитывает строки, включая строки, заполненные NULL. |
| СЧЕТ(столбец) | Подсчитывает строки, в которых этот столбец не равен NULL. |
| COUNT(DISTINCT столбец) | Подсчитывает количество различных значений, игнорируя повторы. |
| GROUP BY | Определяет, в каких строках вычисляется агрегат. |
| Правило GROUP BY | Каждый выбранный столбец либо группируется, либо агрегируется. Никакого третьего варианта. |
| INNER JOIN | Сохраняет только совпадающие пары. Несравненные строки исчезают бесшумно. |
| LEFT JOIN | Сохраняет каждую левую строку, заполняя правую часть NULL там, где ничего не соответствует. |
| Разветвление | Одна строка, совпадающая со многими, создает множество строк, повторяющих значения одной стороны. |
| DISTINCT | Удаляет повторяющиеся строки. Прежде чем использовать его, спросите, откуда они взялись. |
| LIMIT | Возвращает первые н строк. Самый быстрый способ посмотреть на незнакомую таблицу. |
| Псевдоним | Псевдоним столбца или таблицы. AS не является обязательным, но более понятным. |
| CASE | Если-то. Читается сверху вниз, останавливается на первом совпадении, бесподобный переходит в ELSE. |
| подзапрос | Запрос внутри запроса, в FROM как временная таблица или в WHERE как значение. |
| КТР (С) | Именованный результат определен заранее, поэтому запрос читается в том порядке, в котором он работает. |
| оконная функция | Математические вычисления по связанным строкам, которые сохраняют каждую строку. GROUP BY сворачивается, OVER — нет. |
| PARTITION BY | Говорит, какие строки принадлежат одному и тому же окну. |
| ОТСТАВАНИЕ и ВЕДЕНИЕ | Достигните предыдущего или следующего ряда. Как строятся изменения от периода к периоду. |
| первичный ключ | Уникально идентифицирует строку. Никогда не повторяется, никогда NULL. |
| внешний ключ | Этот идентификатор появляется в другой таблице, чтобы указать на него. |
| индекс | Структура поиска, позволяющая базе данных не считывать каждую строку. Индексируйте то, к чему вы присоединяетесь, и фильтруйте. |
Один искренний вопрос, и мне бы хотелось получить ответы от других людей. Идея, которая заняла у меня больше всего времени, была NULL, потому что я продолжал относиться к этому как к ценности, а не как к отсутствию таковой, и она продолжала почти работать. Какую идею SQL вы дольше всего понимали неправильно и что в итоге исправило это?
SQL для аналитиков состоит из 239 страниц, каждый запрос читается построчно простыми словами, а также практические вопросы, которые печатают ответ и причину, по которой он правильный.
SQL для аналитиков, 19 $ →Ссылки
- Кодд, EF (1970). Реляционная модель данных для крупных общих банков данных. Коммуникации ACM, 13(6), 377–387.
- Рёдигер, Х.Л., и Карпике, Дж.Д. (2006). Улучшенное обучение с помощью тестов: прохождение тестов на память улучшает долгосрочное запоминание. Психологическая наука, 17(3), 249–255.
- Сепеда, Нью-Джерси, Пашлер, Х., Вул, Э., Викстед, Дж. Т., и Рорер, Д. (2006). Распределенная практика в задачах на вербальное запоминание: обзор и количественный синтез. Психологический вестник, 132(3), 354–380.
- Чи, М.Т.Х., Бассок, М., Льюис, М.В., Рейманн, П. и Глейзер, Р. (1989). Самообъяснения: как учащиеся изучают и используют примеры при обучении решению проблем. Когнитивная наука, 13(2), 145–182.
тот Курс SQL превращает одни и те же концепции в проработанные примеры, обучающие карточки, лабораторию ПРИСОЕДИНЯЙТЕСЬ К Лаборатории, которая запускает реальную базу данных в браузере, и пробный экзамен — в том порядке, в котором они представлены на этой странице. Ничего устанавливать и учетная запись не требуется.
Откройте набор SQL →Или сразу начните печатать: открыть SQL-практикум, тринадцать запросов, каждый из которых добавляет что-то одно к последнему.