Мне очень трудно писать сложные запросы SQL, включающие объединения по многим (как минимум 3-4) таблицам и включающие несколько вложенных условий. Запросы, которые меня просят написать, легко описываются несколькими предложениями, но для их завершения может потребоваться вводящее в заблуждение количество кода. Я часто использую временные представления для написания этих запросов, которые кажутся чем-то вроде опоры. Какие советы вы можете дать, чтобы я мог упростить эти сложные запросы? Более конкретно, как мне разбить эти запросы на шаги, которые мне нужно использовать, чтобы фактически написать код SQL?
Обратите внимание, что я SQL, который меня просят написать, является частью домашних заданий для курса по базе данных, поэтому я не хочу, чтобы программное обеспечение выполняло эту работу за меня. Я хочу понять код, который я пишу.
Более технические детали:
- База данных размещается на сервере PostgreSQL, работающем на локальной машине.
- База данных очень мала: не более семи таблиц, а самая большая таблица содержит менее 50 строк.
- Запросы SQL передаются на сервер без изменений через LibreOffice Base.
Ответы:
Я основываю большую часть этого на попытках получить «правильный» ответ, чтобы вы могли обнаружить, что есть некоторые проблемы с производительностью. Нет смысла ускорять неправильный запрос.
Поймите отношения таблицы - большинство будет один ко многим. Знать таблицу «многие». Определите поля, необходимые для ваших объединений.
Подумайте о сценариях ЛЕВОГО присоединения - выберите всех сотрудников и их зарплату с прошлого месяца. Что если они не получили зарплату в прошлом месяце?
Знайте набор результатов: 1) В электронной таблице вручную введите хотя бы одну правильную запись для вашего запроса. 2) Напишите запрос в достаточно простой форме, чтобы определить, сколько записей должно быть возвращено. Используйте оба из них, чтобы проверить ваш запрос, чтобы убедиться, что присоединение к новой таблице не изменит результат.
Разбейте ваш запрос на управляемые части - вам не нужно писать все сразу. Сложные запросы иногда могут быть просто набором простых запросов.
Остерегайтесь смешанных уровней агрегации : если вам нужно поместить ежемесячные, квартальные и текущие значения в один и тот же набор результатов, вам нужно будет рассчитать их отдельно в запросах, сгруппированных по разным значениям.
Знайте, когда объединяться Иногда легче разделить подгруппы на свои собственные операторы выбора. Если у вас есть таблица, смешанная с менеджерами и другими сотрудниками, и в каждом столбце вы должны делать операторы Case, основанные на членстве в одной из этих групп, может быть проще написать запрос Manager и объединить его с запросом Employee. Каждый из них будет содержать свою собственную логику. Необходимость включать элементы из разных таблиц в разные строки - очевидное применение.
Сложные / вложенные формулы - Старайтесь последовательно делать отступы и не бойтесь использовать несколько строк. «Дело, когда дело, когда дело, когда» сводит вас с ума. Потратьте время, чтобы обдумать это. Сохраните сложные кальки для последнего. Получите правильные записи, выбранные в первую очередь. Затем вы атакуете сложные формулы, зная, что работаете с правильными значениями. Просмотр значений, используемых в формулах, поможет вам определить области, в которых необходимо учитывать значения NULL, и где обрабатывать ошибку деления на ноль.
Тестируйте часто, когда вы добавляете новые таблицы, чтобы убедиться, что вы все еще получаете желаемый набор результатов и знаете, какое соединение или предложение является виновником.
источник
Отступ будет первым делом, если вы еще этого не делаете. Он не только полезен даже для простых запросов, но и важен, когда речь идет о соединениях и запросах, которые немного сложнее, чем a
select top 1 [ColumnName] from [TableName]
.После правильного отступа ничто не запрещает добавлять комментарии внутри самого запроса, когда это уместно. Не злоупотребляйте ими: если код достаточно явный, добавление комментариев только повредит ясности кода. Но они все еще приветствуются для менее явных частей запроса.
Обратите внимание, что более длинные запросы (включая запросы с комментариями) означают более широкое использование полосы пропускания между сервером приложений и сервером базы данных. Также обратите внимание, что если вы не работаете с продуктом масштаба Google с огромным количеством запросов в секунду, требующим исключительной производительности и использования ресурсов, размер, добавленный комментариями, может ничего не изменить для вас с точки зрения производительности.
Применение одного и того же стиля к таблицам, столбцам и т. Д. Также значительно улучшает читабельность. Когда наследство база данных таблиц
PRODUCT
,users
,USERS_ObsoleteDONT_USE
,PR_SHIPMENTS
иHRhbYd_UU
, кто - то делает что - то очень неправильно.Применение одного стиля к запросам также важно. Например, если вы пишете запросы для Microsoft SQL Server и решили использовать
[TableName]
вместоTableName
, придерживайтесь его. Если после a вы переходите на новую строкуselect
, делайте это не только в половине запросов, но во всех.Не используйте
*
, если нет веских причин для этого (например,if exists(select * from [TableName] where ...)
в Microsoft SQL Server). Это не только*
отрицательно влияет на производительность в некоторых (если не в большинстве) базах данных, но также не помогает разработчику, использующему ваш запрос. Таким же образом, разработчик должен получить доступ к значениям по имени, а не по индексу.Наконец, для выбора нет ничего плохого в предоставлении представления . Для чего-то еще, хранимые процедуры могут также использоваться в зависимости от проекта и людей, с которыми вы работаете.
People Некоторые люди ненавидят хранимые процедуры. Другим они не нравятся по нескольким (вполне обоснованным, по крайней мере для них) причинам.
² Ваши коллеги, другие ученики, ваш учитель и т. Д.
источник
Немного в темноте, но если вы пишете много временных представлений, возможно, вы еще не осознали, что в большинстве мест вы можете поместить таблицу в оператор SQL, эту таблицу можно заменить запросом.
Таким образом, вместо присоединения таблицы A к временному представлению B вы можете присоединить таблицу A к запросу, который вы использовали в качестве временного представления B. Например:
Этот пример довольно бессмысленный, но должен объяснить синтаксис.
Для представлений, которые не являются «специальными» (проиндексированными, секционированными), это должно привести к тому же плану запросов, как если бы вы использовали представление.
Для облегчения написания вы можете проверить каждый фрагмент, чтобы убедиться, что вы получаете то, что ожидаете, прежде чем писать весь запрос.
Приношу свои извинения, если это уже старая шляпа для вас.
источник
Вместо временных представлений используйте предложение WITH . Это значительно облегчает разбиение больших запросов на более читаемые меньшие части.
источник
источник
Как и все остальное, вы хотите разбить проблему на управляемые части.
Кстати, именно так вы решаете сложные проблемы.
Итак: вы хотите проверить подзапрос, чтобы увидеть, что он действительно возвращает то, что вы хотите, прежде чем выполнять внешний запрос к нему. Вы хотите попробовать минимальное объединение каждой таблицы, в которую вы входите, чтобы убедиться, что вы действительно продумали все правильно. Такие вещи. Надеяться набрать все это и получить именно то, что вы хотите одним ударом, просто нереально.
Оператор SQL, когда он достигает определенного уровня сложности, сам по себе является небольшой программой. Очень важно понимать, как данные объединяются, отбираются, фильтруются и выводятся.
источник