Запрос SELECT: как читать строки из таблицы
Любой вопрос к базе SQLite начинается со слова SELECT. По сути, вы говорите: верни мне такие-то столбцы, из такой-то таблицы, по строкам, которые подходят под такие-то условия. Сегодня разбираемся с первыми двумя частями — столбцами и таблицей. Про фильтрацию поговорим в следующей статье.
Самый простой запрос select выглядит так:
SELECT * означает «все столбцы», а FROM products указывает таблицу. На выходе получим по одной строке на каждую запись со всеми четырьмя столбцами. Точка с запятой закрывает выражение.
Вот и весь шаблон: SELECT <столбцы> FROM <таблица>;.
Выборка конкретных столбцов в SQLite
Звёздочка * удобна, когда вы только знакомитесь с данными. Но в боевом коде почти всегда лучше явно перечислять нужные столбцы:
Вы получите два столбца ровно в том порядке, в котором их перечислили. Порядок в списке SELECT определяет порядок в результате — он вовсе не обязан совпадать с порядком столбцов в самой таблице.
Почему это лучше, чем SELECT *? Есть две причины. Во-первых, меньше данных передаётся (или читается из файла), а это уже ощутимо, когда таблицы становятся широкими. Во-вторых, ваш запрос не сломается, если через месяц кто-то добавит в таблицу новый столбец. SELECT * тихо начнёт возвращать больше данных, и это запросто положит код приложения, который разбирает строки по позиции.
SELECT умеет не только доставать, но и вычислять
В списке SELECT могут быть не только имена столбцов. Туда годится любое выражение — арифметика, вызовы функций, склейка строк, константы. SQLite вычисляет такое выражение для каждой строки.
Четвёртого столбца в таблице нет — SQLite вычислил его построчно. Так же можно поступать со строковыми функциями, датами, условными выражениями — да с чем угодно. Список SELECT — это не просто способ достать данные, а полноценный инструмент для их преобразования.
Более того, SELECT можно выполнить вообще без FROM, превратив SQLite в обычный калькулятор:
Одна строка, три столбца. Удобно, когда нужно проверить, как поведёт себя выражение, прежде чем вставлять его в реальный запрос.
Псевдонимы столбцов через AS
Когда вы вычисляете столбец, SQLite сам подбирает ему имя по умолчанию — обычно это просто текст самого выражения, например price * stock. Выглядит некрасиво и легко ломается при изменениях. Лучше задать столбцу нормальное имя через AS:
Псевдоним — это имя столбца в результирующем наборе. Это важно для читаемости при просмотре вывода, и особенно важно для прикладного кода, который достаёт значения по имени столбца (row["inventory_value"] вместо row[1]).
Ключевое слово AS необязательно — запись price * stock inventory_value сработает точно так же, — но лучше его всё-таки писать. Намерение становится яснее, и вы не запутаете читателя, который может принять пропущенную запятую за псевдоним.
Псевдоним и для самой таблицы
Короткий псевдоним можно дать и самой таблице. С одной таблицей это почти бесполезно, но привычка окупится, как только вы начнёте делать JOIN'ы:
p теперь работает как сокращение для products. Запись через точку p.name явно говорит, из какой таблицы взят столбец. Когда таблица одна — это лишний шум, но когда у вас джойнятся три таблицы, именно такая запись и спасает читаемость запроса.
Литералы и константы в результате выборки
В SELECT можно спокойно смешивать реальные столбцы с константами. Удобно, когда хочется пометить строки или подставить какое-то значение по умолчанию:
Каждая строка получает одно и то же значение 'USD' и 1. Такой приём часто встречается, когда вы объединяете результаты нескольких запросов через UNION и нужен столбец-маркер, чтобы различать источники.
Пара слов о NULL
Некоторые столбцы оказываются пустыми — значение не было вставлено, либо у столбца нет значения по умолчанию. В SQLite «отсутствие значения» обозначается как NULL, и в результатах SELECT оно отображается либо пустотой, либо словом NULL — всё зависит от того, в какой утилите вы смотрите данные.
Посмотрите на вторую строку. price равен NULL, и price * 2 тоже NULL — любая арифметика с NULL даёт NULL. Это один из самых частых источников путаницы в результатах SQL-запросов, и про него у нас будет отдельная страница. Пока просто запомните: NULL «заражает» все выражения, в которые попадает.
Что стоит запомнить
SELECT <столбцы> FROM <таблица>;— это скелет любого запроса.- В рабочем коде всегда перечисляйте столбцы явно;
SELECT *оставьте для разведки данных. - В списке
SELECTможно писать любые выражения, а не только имена столбцов. - Используйте
AS, чтобы давать вычисляемым столбцам и таблицам осмысленные псевдонимы. NULLраспространяется через арифметику — держите это в голове, когда результат выглядит странно.
Дальше: фильтрация через WHERE
Пока что все наши запросы возвращают все строки таблицы. Чтобы сузить выборку, используется WHERE — он позволяет отбирать строки по цене, по имени, по дате, по любому выражению, которое можно свести к истине или лжи. Об этом — в следующей статье.
Часто задаваемые вопросы
Как выглядит базовый синтаксис SELECT в SQLite?
SELECT <столбцы> FROM <таблица>;. В качестве столбцов можно перечислить их через запятую (SELECT name, email FROM users), поставить *, чтобы взять всё, или написать любое выражение, например price * quantity. FROM указывает таблицу, из которой читаем, а точка с запятой завершает запрос.
Стоит ли использовать SELECT * в SQLite?
Для быстрой разведки в CLI — почему бы и нет, удобно посмотреть, что вообще лежит в таблице. А вот в коде приложения лучше явно перечислять нужные столбцы. SELECT * намертво привязывает код к текущей схеме: добавите завтра новую колонку — и запрос молча начнёт возвращать больше данных, что легко поломает код, который разбирает строки по позициям.
Как переименовать столбец в результате SELECT?
Через AS — задаём псевдоним для столбца или выражения: SELECT price * quantity AS total FROM orders. Псевдоним становится именем колонки в результате, а это важно и для читаемости, и для кода, который обращается к полям по имени. Само ключевое слово AS формально необязательно, но писать его стоит — так понятнее.