Как стать автором
Обновить
61.18

SQL *

Формальный непроцедурный язык программирования

Сначала показывать
Порог рейтинга
Уровень сложности

Моя большая практическая шпаргалка SQL (SQLite) с готовыми запросами

Уровень сложностиСредний
Время на прочтение54 мин
Количество просмотров77K

Привет, Хабр)

Публикую шпаргалку по SQL, которая долгое время помогала мне, да и сейчас я периодически в неё заглядываю.

Все примеры изначально писались для СУБД SQLite, но почти всё из этого применимо также и к другим СУБД.

Здесь есть и примеры довольно сложных запросов с агрегирующими функциями, триггерами, длинными подзапросами, с оконными функциями. Помимо этого, часть примеров посвящена работе с SQL в Python, используя sqlite3, pandas, polars. Этот список запросов с комментариями можно использовать как наглядное пособие для изучения SQL.

Читать далее
Всего голосов 125: ↑122 и ↓3+119
Комментарии7

Новости

Моя большая практическая шпаргалка SQL (SQLite) с готовыми запросами

Уровень сложностиСредний
Время на прочтение54 мин
Количество просмотров77K

Привет, Хабр)

Публикую шпаргалку по SQL, которая долгое время помогала мне, да и сейчас я периодически в неё заглядываю.

Все примеры изначально писались для СУБД SQLite, но почти всё из этого применимо также и к другим СУБД.

Здесь есть и примеры довольно сложных запросов с агрегирующими функциями, триггерами, длинными подзапросами, с оконными функциями. Помимо этого, часть примеров посвящена работе с SQL в Python, используя sqlite3, pandas, polars. Этот список запросов с комментариями можно использовать как наглядное пособие для изучения SQL.

Читать далее
Всего голосов 125: ↑122 и ↓3+119
Комментарии7

С новым годом: GPT в 500 строках на SQL

Время на прочтение42 мин
Количество просмотров37K

В минувшем году все только и говорили об ИИ и о том, как он может всё за вас сделать.

Мне нравится, когда кто-то или что-то работает за меня. Поэтому решил: попрошу-ка ChatGPT написать за меня новогодний пост:

«Эй, ChatGPT. А ты можешь реализовать большую языковую модель на SQL?»
«Нет, SQL не подходит для реализации больших языковых моделей. Язык SQL предназначен для выполнения запросов к данным, хранящимся в РСУБД и для управления этими запросами. Для реализации большой языковой модели требуются сложные алгоритмы, обширные датасеты, а зачастую — и фреймворки для глубокого обучения. SQL всеми этими возможностями не обладает.»

Что ж, лишний раз убеждаешься, что, если хочешь что‑то сделать хорошо – сделай это сам.

Давайте же воодушевимся этим оптимистическим планом и реализуем большую языковую модель на языке SQL.

Читать далее
Всего голосов 215: ↑211 и ↓4+207
Комментарии21

Шпаргалка по SQL (postgres), которая выручает меня на собесах

Уровень сложностиПростой
Время на прочтение8 мин
Количество просмотров183K

Привет, Хабр!

Я решил посвятить свою первую статью SQL. Вопросы, рассмотренные ниже мне задавали на собеседованиях на позицию python-разработчика. Естественно отвечать правильно получалось не всегда, а если точнее то чаще не правильно, однако проведя N часов в рефлексии я составил перечень ответов, которыми пользуюсь до сих пор.

Данная информация предполагает знание основ языка запросов и я надеюсь, она окажется полезной для разработчиков, которые сейчас активно ищут работу а также, что ты прочитаешь этот текст до конца и добавишь свой вопрос к перечню (ну или поправишь неточности в существующих)

Читать далее
Всего голосов 191: ↑184 и ↓7+177
Комментарии177

Истории

SQLite — не игрушка

Время на прочтение7 мин
Количество просмотров79K

Рассказываю, почему SQLite отлично подойдет вам в повседневной работе. И неважно, разработчик вы, аналитик, тестировщик, админ или продакт-менеджер.

Читать далее
Всего голосов 239: ↑237 и ↓2+235
Комментарии89

Вред хранимых процедур

Время на прочтение3 мин
Количество просмотров52K

В чат подкаста «Цинковый прод» скинули статью о том, как некие ребята перенесли всю бизнес-логику в хранимые процедуры на языке pl/pgsql. И так как у статьи было много плюсов, то значит, есть люди, а может быть, их даже большинство, которые положительно восприняли такой рефакторинг.

Я не буду растекаться мыслью по древу, а сразу накидаю кучку минусов использования хранимых процедур.
Читать дальше →
Всего голосов 175: ↑140 и ↓35+105
Комментарии535

Скулятчер

Время на прочтение6 мин
Количество просмотров33K

Сижу я вчера спокойно, как водится никого особо не трогаю. Тут с двух разных контактов, почти одновременно присылают ссылку на небезызвестный твит про JSON из SQL. Одно из сообщений выглядело так:



Это был уже прямой вызов. Игнорировать его я не мог. Поэтому решил рассказать историю, которая до сих пор вызывает во мне двойственные чувства. Спустя три года.

Читать дальше →
Всего голосов 106: ↑106 и ↓0+106
Комментарии103

Трехмерный движок внутри запроса SQL

Время на прочтение8 мин
Количество просмотров40K
Несколько лет назад на форуме SQL.ru решили провести сравнение реализаций трассировщиков лучей на разных языках программирования. К сожалению, моя заявка не может участвовать т.к. она не выводит надпись «PIXAR», поэтому публикую ее здесь.

Для чистоты эксперимента я использовал SQLite без расширений. Оказалось, что там нет даже функции SQRT.

WITH RECURSIVE numbers AS (SELECT 0 AS n UNION ALL SELECT n+1 FROM numbers WHERE n<89),
pixels AS (SELECT rows.n as row, cols.n as col FROM numbers as rows CROSS JOIN
numbers as cols WHERE rows.n > 4 AND rows.n < 38 AND cols.n > 9 AND cols.n < 89),
rawRays AS (SELECT row, col, -0.9049 + col * 0.0065 + row * 0.0057 as x,
-0.1487 + row * -0.0171 as y, 0.6713 + col * 0.0045 + row * -0.0081 as z FROM pixels),
norms AS (SELECT row, col, x, y, z, (1 + x * x + y * y + z * z) / 2 as n FROM rawRays),
rays AS (SELECT row, col, x / n AS x, y / n AS y, z / n AS z FROM norms),
iters AS (SELECT row, col, 0 as it, 0 as v FROM rays UNION ALL
SELECT rays.row, rays.col, it + 1 AS it, v + MAX(ABS(0.7+v*x) - 0.3,
ABS(0.7+v*y) - 0.3, ABS(-1.1+v*z) - 0.3, -((0.7+v*x) * (0.7+v*x) +
(0.7+v*y) * (0.7+v*y) + (-1.1+v*z) * (-1.1+v*z)) * 1.78 + 0.28) AS v
FROM iters JOIN rays ON rays.row = iters.row AND rays.col = iters.col WHERE it < 15),
lastIters AS (SELECT it0.row, it0.col, it0.v AS v0, it1.v AS v1, it2.v AS v2
FROM iters as it0 JOIN iters AS it1 ON it0.col = it1.col AND it0.row = it1.row
JOIN iters AS it2 ON it0.col = it2.col AND it0.row = it2.row
WHERE it0.it = 15 AND it1.it = 14 AND it2.it = 13),
res AS (SELECT col, (v0 - v1) / (v1 - v2) as v FROM lastIters)
SELECT group_concat(
substr('$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,"^. ',
round(1 + max(0, min(66, v * 67))), 1) || CASE WHEN col=88 THEN X'0A' ELSE '' END, '')
FROM res;



Здесь можно покрутить кубик

Под катом построчный разбор запроса. Как обычно, достаточно знания основ SQL и школьной математики.
Читать дальше →
Всего голосов 169: ↑168 и ↓1+167
Комментарии24

Нет, вам не нужно машинное обучение. Вам нужен SQL

Время на прочтение5 мин
Количество просмотров63K
Некоторое время назад я опубликовал серию твитов об использовании традиционных инструментов вместо новомодных и сложных технологий.

Твиты зашли неплохо и попали на HackerNews. Последствием такой мини-популярности стала интересная дискуссия. Одни согласились со мной, а другие назвали это глупостью и бредом. Ну, в интернете тоже случаются перестрелки.

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

Годы проходят, и вы наблюдаете появление некоторых интересных технологий и концепций: машинное обучение, блокчейн, искусственный интеллект, виртуальная реальность, дополненная реальность и т. д. — в то время как некоторые прежние технологии уходят на задний план. Сегодня несложно услышать о разработке каких-то фантастических продуктов на блокчейне. Я видел блокчейн-сервисы для электронной коммерции, социальных сетей и недвижимости. Список можно продолжить. Я слышу слова: чтобы вам быстрее и раньше закрыть раунд финансирования, нужно использовать слово «блокчейн», даже если оно не имеет отношения к проекту.
Читать дальше →
Всего голосов 122: ↑112 и ↓10+102
Комментарии417

И так сойдёт… или как данные 14 миллионов россиян оказались у меня в руках

Время на прочтение6 мин
Количество просмотров139K
Одиноким вечером, глядя на свою пустую зачётку и осознавая, что конец близок, я снова задумался о том, как бы мне сейчас собрать сумку, или даже просто рюкзак, положить туда рубашку, шорты и свалить в тёплую страну. Было бы хорошо, да вот с дипломом живётся намного лучше. Во всяком случае, мне всегда так говорят.

Также часто слышал много историй про людей, которые приходили на собеседования с красными дипломами МГУ, но при этом абсолютно не разбирались в своей специальности, а потом на корпоративах признавались, что диплом у них купленный.

Но времена сейчас другие, сейчас 21 век, век больших возможностей, любой работодатель, который умеет пользоваться мышкой и знает, как выглядит браузер на рабочем столе, может проверить данные диплома. Каждый диплом, который выдаётся учебным заведением, теперь регистрируется в едином реестре, доступ к которому есть у каждого через сайт Федеральной службы по надзору в сфере образования и науки.

image

Внимание: не пытайтесь повторять действия, описанные в публикации и им подобные. Помните о ст. 272 УК РФ «Неправомерный доступ к компьютерной информации».

Читать дальше →
Всего голосов 360: ↑346 и ↓14+332
Комментарии812

Индексы в PostgreSQL — 1

Время на прочтение17 мин
Количество просмотров392K

Предисловие


В этой серии статей речь пойдет об индексах в PostgreSQL.

Любой вопрос можно рассматривать с разных точек зрения. Мы будем говорить о том, что должно интересовать прикладного разработчика, использующего СУБД: какие индексы существуют, почему в PostgreSQL их так много разных, и как их использовать для ускорения запросов. Пожалуй, тему можно было бы раскрыть и меньшим числом слов, но мы втайне надеемся на любознательного разработчика, которому также интересны и подробности внутреннего устройства, тем более, что понимание таких подробностей позволяет не только прислушиваться к чужому мнению, но и делать собственные выводы.

За скобками обсуждения останутся вопросы разработки новых типов индексов. Это требует знания языка Си и относится скорее к компетенции системного программиста, а не прикладного разработчика. По этой же причине мы практически не будем рассматривать программные интерфейсы, а остановимся только на том, что имеет значение для использования уже готовых к употреблению индексов.

В этой части мы поговорим про разделение сфер ответственности между общим механизмом индексирования, относящимся к ядру СУБД, и отдельными методами индексного доступа, которые в PostgreSQL можно добавлять как расширения. В следующей части мы рассмотрим интерфейс метода доступа и такие важные понятия, как классы и семейства операторов. После такого длинного, но необходимого введения мы подробно рассмотрим устройство и применение различных типов индексов: Hash, B-tree, GiST, SP-GiST, GIN и RUM, BRIN и Bloom.
Читать дальше →
Всего голосов 104: ↑103 и ↓1+102
Комментарии59

Uber — причины перехода с Postgres на MySQL

Время на прочтение19 мин
Количество просмотров102K


В конце июля 2016 года в корпоративном блоге Uber появилась поистине историческая статья о причинах перехода компании с PostgreSQL на MySQL. С тех пор в жарких обсуждениях этого материала было сломано немало копий, аргументы Uber были тщательно препарированы, компанию обвинили в предвзятости, технической неграмотности, неспособности эффективно взаимодействовать с сообществом и других смертных грехах, при этом по горячим следам в Postgres было внесено несколько изменений, призванных решить некоторые из описанных проблем. Список последствий на этом не заканчивается, и его можно продолжать еще очень долго.


Наверное, не будет преувеличением сказать, что за последние несколько лет это стало одним из самых громких и резонансных событий, связанных с СУБД PostgreSQL, которую мы, к слову сказать, очень любим и широко используем. Эта ситуация наверняка пошла на пользу не только упомянутым системам, но и движению Free and Open Source в целом. При этом, к сожалению, русского перевода статьи так и не появилось. Ввиду значимости события, а также подробного и интересного с технической точки зрения изложения материала, в котором в стиле «Postgres vs MySQL» идет сравнение физической структуры данных на диске, организации первичных и вторичных индексов, репликации, MVCC, обновлений и поддержки большого количества соединений, мы решили восполнить этот пробел и сделать перевод оригинальной статьи. Результат вы можете найти под катом.

Читать дальше →
Всего голосов 112: ↑110 и ↓2+108
Комментарии58

История успеха «Яндекс.Почты» с PostgreSQL

Время на прочтение13 мин
Количество просмотров53K


Владимир Бородин (на «Хабре» dev1ant), системный администратор группы эксплуатации систем хранения данных в «Яндекс.Почте», знакомит со сложностями миграции крупного проекта с Oracle Database на PostgreSQL. Это — расшифровка доклада с конференции HighLoad++ 2016.

Всем привет! Меня зовут Вова, сегодня я буду рассказывать про базы данных «Яндекс.Почты».

Сначала несколько фактов, которые будут иметь значение в будущем. «Яндекс.Почта» — сервис достаточно старый: он был запущен в 2000 году, и потому мы накопили много legacy. У нас — как это принято и модно говорить — вполне себе highload-сервис, больше 10 миллионов пользователей в сутки, какие-то сотни миллионов всего. В бэкенд нам прилетает более 200 тысяч запросов в секунду в пике. Мы складываем более 150 миллионов писем в сутки, прошедших проверки на спам и вирусы. Суммарный объём писем за все 16 лет — больше 20 петабайт.

О чем пойдет речь? О том, как мы перевезли метаданные из Oracle в PostgreSQL. Метаданных там не петабайты — их чуть больше трехсот терабайт. В базы влетает более 250 тысяч запросов в секунду. Надо иметь в виду, что это маленькие OLTP-запросы, по большей части чтение (80%).

Это — не первая наша попытка избавиться от Oracle. В начале нулевых была попытка переехать на MySQL, она провалилась. В 2007 или 2008 была попытка написать что-то своё, она тоже провалилась. В обоих случаях был провал не столько по технически причинам, сколько по организационным.
Всего голосов 113: ↑111 и ↓2+109
Комментарии119

Ближайшие события

Яндекс открывает ClickHouse

Время на прочтение14 мин
Количество просмотров167K
Сегодня внутренняя разработка компании Яндекс — аналитическая СУБД ClickHouse, стала доступна каждому. Исходники опубликованы на GitHub под лицензией Apache 2.0.



ClickHouse позволяет выполнять аналитические запросы в интерактивном режиме по данным, обновляемым в реальном времени. Система способна масштабироваться до десятков триллионов записей и петабайт хранимых данных. Использование ClickHouse открывает возможности, которые раньше было даже трудно представить: вы можете сохранять весь поток данных без предварительной агрегации и быстро получать отчёты в любых разрезах. ClickHouse разработан в Яндексе для задач Яндекс.Метрики — второй по величине системы веб-аналитики в мире.

В этой статье мы расскажем, как и для чего ClickHouse появился в Яндексе и что он умеет; сравним его с другими системами и покажем, как его поднять у себя с минимальными усилиями.
Читать дальше →
Всего голосов 176: ↑172 и ↓4+168
Комментарии204

Несколько интересных особенностей MySQL

Время на прочтение8 мин
Количество просмотров63K
В не очень далеком прошлом мне пришлось покопаться немного в исходном коде MySQL, и разобраться в некоторых аспектах его работы. В ходе работы лопаткой, и эксперимeнтов, я наткнулся на несколько очень интересных особенностей, часть из которых просто забавна, а в случае некоторых бывает очень интересно понять, чем руководствовался программист, который принимал решение сделать именно так.

Начнем с такого интересного типа, как ENUM.

mysql> CREATE TABLE enums(a ENUM('c', 'a', 'b'), b INT, KEY(a));
Query OK, 0 rows affected (0.36 sec)

mysql> INSERT INTO enums VALUES('a', 1), ('b', 1), ('c', 1);
Query OK, 3 rows affected (0.05 sec)
Records: 3  Duplicates: 0  Warnings: 0


Итак, у нас есть таблица, в ней есть два столбца. У первого, a, тип ENUM, у второго, b, INT. В таблице три строки, у всех трех значение b равно 1. Интересно, чему равны минимальный и максимальный элементы в столбце a?

mysql> SELECT MIN(a), MAX(a) FROM enums;
+--------+--------+
| MIN(a) | MAX(a) |
+--------+--------+
| c      | b      |
+--------+--------+
1 row in set (0.00 sec)


Кажется странным, было бы разумно, если бы самым маленьким был 'a', а самым большим — 'c'.
А что если выбрать минимум и максимум только среди тех строк, где b = 1? То есть, среди всех строк?

mysql> SELECT MIN(a), MAX(a) FROM enums WHERE b = 1;
+--------+--------+
| MIN(a) | MAX(a) |
+--------+--------+
| a      | c      |
+--------+--------+
1 row in set (0.00 sec)


Вот так мы заставили MySQL поменять свое мнение о том, как сравнивать поля в ENUM, просто добавив предикат.
Разгадка такого поведения заключается в том, что в первом случае MySQL использует индекс, а во втором нет. Это, конечно, не объясняет, почему MySQL сравнивает ENUMы по разному для сортировки в индексе, и при обычном сравнении.

Второй пример проще и лаконичнее:

mysql> (SELECT * FROM moo LIMIT 1) LIMIT 2;
+------+
| a    |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)


Когда я показал этот запрос своему коллеге, который занимается разработкой парсера SQL, его вопрос был не «почему этот запрос возвращает две строки», а «как надо написать SQL парсер так, чтобы такой запрос был валидным, без того, чтобы написать правило, специально разрешающее такой запрос».

Интересно, что далеко не любой SELECT в скобках сработает, в частности, UNION в скобках — это синтаксическая ошибка:

mysql> (SELECT * FROM moo UNION ALL SELECT * FROM hru) LIMIT 2;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION ALL SELECT * FROM hru) LIMIT 2' at line 1


Еще несколько интересных примеров под катом
Читать дальше →
Всего голосов 113: ↑110 и ↓3+107
Комментарии95

Как мы запрос в 100 раз ускоряли, или не все хеш-функции одинаково плохи

Время на прочтение4 мин
Количество просмотров37K
Мы разрабатываем базу данных. Однажны к нам обратилась компания, которая столкнулась со следующей задачей:

Есть некоторое множество объектов, и некоторое множество тегов. Каждый объект может содержать несколько тегов. Какие-то теги очень редкие, а какие-то встречаются часто. Одному объекту один тег может быть сопоставлен несколько раз.
Новые объекты, теги и связи между ними непрерывно добавляются.
Задача — очень быстро отвечать на вопросы вида: «сколько есть объектов, у которых есть тег А или B, но нету тега С» и похожие. На такие запросы хотелось бы отвечать за десятые доли секунды, при этом не останавливая загрузку данных.

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

SELECT 
    COUNT(*) 
FROM (
    SELECT 
        object_id, 
        (MAX(tag == A) OR MAX(tag == B)) AND MIN(tag != C) AS good
    FROM tags
    WHERE tag IN (A, B, C)
    GROUP BY object_id
) WHERE good == 1;


Чтобы такой запрос выполнялся быстро, мы разбили данные между серверами кластера по object_id, а внутри каждого сервера отсортировали их по тегам. Таким образом сервер, выполняющий запрос, может отправить запрос без изменений на все сервера с данными, а затем просто сложить их результаты. На каждом сервере с данными для выполнения запроса достаточно найти строки для тегов A, B и C (а так как данные по тегу отсортированы, это быстрая операция), после чего выполнить запрос за один проход по этим строкам. Худший тег имеет несколько десятков миллионов объектов, несколько десятков миллионов строк обработать за десятые доли секунды видится возможным.
Стоит отметить, что подзапрос содержит GROUP BY object_id. GROUP BY в данной ситуации можно выполнить несколькими способами, например, если данные после тега отсортированы по object_id, то можно выполнить что-то похожее на merge sort. В данной ситуации, однако, мы данные по object_id не отсортировали, и оптимизатор разумно решил, что для выполнения GROUP BY надо построить хеш-таблицу.

Мы загрузили все данные в кластер, и запустили запрос. Запрос занял 25 секунд.
Читать дальше →
Всего голосов 107: ↑104 и ↓3+101
Комментарии4

Решение японских кроссвордов одним запросом SQL

Время на прочтение4 мин
Количество просмотров59K
Привет хабр! Приближается день программиста, и я спешу поделиться своими ненормальными наработками.

Японский кроссворд — NP-полная задача, как и задача коммивояжёра, укладки рюкзака и др. Когда ее решает человек, следует последовательно определять гарантированно заполненные и пустые ячейки. Одну за другой вычеркивать колонки и строки, пока не сложится весь рисунок. Как же возможно запрограммировать решение подобной задачи на языке, который официально даже не является языком программирования, не содержит циклов и переменных? SQL — язык запросов, его главная задача — выбирать строки. Вот мы и будем генерировать множество всех возможных перестановок и, словно скульптор, отсекать все лишнее.

укусить себя за пятку
Всего голосов 172: ↑165 и ↓7+158
Комментарии26

Девушка с татуировкой ANSI

Время на прочтение2 мин
Количество просмотров19K
Специалисты по СУБД с сайта Oracle WTF заинтересовались, что же такое печатает в терминале юный хакер в фильме «Девушка с татуировкой дракона». По сюжету, это были запросы к базе данных полицейского отделения, с помощью которых она раскрыла убийства 40-летней давности.


Читать дальше →
Всего голосов 226: ↑171 и ↓55+116
Комментарии286

Не БД

Время на прочтение6 мин
Количество просмотров9.2K
Автор рассказывает о перипетиях пивоваров, производителей СУБД, себя и кратко о том как правильно проектировать приложения. Мне показалась полезной поучительная часть статьи.
Читать дальше →
Всего голосов 122: ↑113 и ↓9+104
Комментарии175

Вклад авторов