Вопрос по теории SQL-запросов - запросы с одним оператором против запросов с несколькими операторами

StackOverflow https://stackoverflow.com/questions/2015290

Вопрос

Когда я пишу SQL-запросы, я часто ловлю себя на мысли, что "нет никакого способа сделать это с помощью одного запроса".Когда это происходит, я часто обращаюсь к хранимым процедурам или многозначным табличным функциям с несколькими инструкциями, которые используют временные таблицы (того или иного вида) и в конечном итоге просто объединяют результаты и возвращают результирующую таблицу.

Мне интересно, знает ли кто-нибудь, просто теоретически, является ли это следует быть возможным написать ЛЮБОЙ запрос, который возвращает один результирующий набор, в виде одного запроса (а не нескольких инструкций).Очевидно, что я игнорирую важные моменты, такие как читаемость кода и ремонтопригодность, возможно, даже производительность запросов.Это больше о теории - можно ли это сделать...и не волнуйтесь, я, конечно, не планирую заставлять себя писать запрос с одним оператором, когда во всех случаях для моих целей лучше подойдет запрос с несколькими операторами, но это может заставить меня дважды или чуть дольше подумать о том, существует ли жизнеспособный способ получить результат из одного запроса.

Я предполагаю, что несколько параметров в порядке - я имею в виду реляционную базу данных (такую как MS SQL) с таблицами, которые соответствуют общепринятым рекомендациям (например, все таблицы имеют первичный ключ и так далее).

Примечание:чтобы получить "Принятый ответ" на этот вопрос, вам нужно будет предоставить окончательное доказательство (ссылку на веб-материал или что-то подобное).)

Это было полезно?

Решение

По крайней мере, с последней версией Oracle это абсолютно возможно.В нем есть "модельное предложение", которое делает sql turing завершенным.( http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/ ).Конечно, все это с обычным ограничением в том, что на самом деле у нас нет неограниченного времени и памяти.

Для обычного диалекта sql без этих дополнений я не думаю, что это возможно.

Задача, которую я не вижу, как реализовать в "обычном sql", была бы:Предположим, что имеется таблица с одним столбцом типа integer

Для каждой строки 'возьмите значение в текущей строке и вернитесь на столько строк назад, извлеките это значение, вернитесь на столько строк назад и продолжайте, пока не получите одно и то же значение дважды подряд и не вернете его в качестве результата.'

Другие советы

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

Я никогда не сталкивался с чем-то, что не могло быть выполнено в одном запросе.
Но иногда лучше всего сделать это в нескольких запросах.

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

Я бы сказал "да", но не могу этого доказать.Однако мой основной мыслительный процесс:

  • Любой выбор должен быть операцией, основанной на наборе

  • Ваше предположение заключается в том, что вы имеете дело с математически правильными наборами (т. е. правильно нормализованными)

  • Теория множеств должна гарантировать, что это возможно

Другие мысли:

  • Оператор множественного выбора часто загружает временные таблицы / табличные переменные.Они могут быть производными или разделены в CTE.

  • Любая обработка RBAR (хорошая или плохая) теперь обрабатывается ПЕРЕКРЕСТНЫМ / ВНЕШНИМ применением к производным таблицам

  • Мне кажется, в этом контексте UDFS был бы классифицирован как "обман", потому что он позволяет вам поместить SELECT в другой модуль, а не в ваш единственный

  • В вашей последовательности DML "до" записи запрещены:это изменяет состояние с SELECT на SELECT

  • Вы видели какой-нибудь код в нашем магазине?

Редактировать, глоссарий

Редактировать:ПРИМЕНЯТЬ:изменяешь?

SELECT
    *
FROM
    MyTable1 t1
    CROSS APPLY
    (
        SELECT * FROM MyTable2 t2
        WHERE t1.something = t2.something
    ) t2

Теоретически да, если вы используете функции или извилистый лабиринт ВНЕШНИХ приложений или подзапросов;однако для удобства чтения и производительности мы всегда в конечном итоге использовали временные таблицы и хранимые процедуры с несколькими операторами.

Как кто-то прокомментировал выше, обычно это признак того, что ваша структура данных начинает попахивать;не то чтобы это плохой, но, возможно, пришло время денормализовать из соображений производительности (случается с лучшими из нас), или, может быть, поместить денормализованный слой запросов перед вашими нормализованными "реальными" данными.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top