Вопрос теории SQL-запросов - запросы с одним оператором против запросов с несколькими операторами - PullRequest
6 голосов
/ 06 января 2010

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

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

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

Примечание: чтобы выиграть «Принятый ответ», вам необходимо предоставить окончательное доказательство (ссылка на веб-материал или что-то подобное).

Ответы [ 5 ]

3 голосов
/ 06 января 2010

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

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

2 голосов
/ 06 января 2010

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

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

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

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

2 голосов
/ 06 января 2010

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

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

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

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

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

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

  • Любая обработка RBAR (хорошая или плохая) теперь обрабатывается CROSS / OUTER APPLY для производных таблиц

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

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

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

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

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

SELECT
    *
FROM
    MyTable1 t1
    CROSS APPLY
    (
        SELECT * FROM MyTable2 t2
        WHERE t1.something = t2.something
    ) t2
2 голосов
/ 06 января 2010

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

1 голос
/ 06 января 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...