Функции FIRST_VALUE и LAST_VALUE |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Для каждой компании выводить один рейс, выбираемый случайным образом (база данных аэропорт).Использование коррелирующего подзапросаВ подзапросе для каждой компании данные сортируются случайным образом при использовании функции newid(), после чего выбирается одна (первая строка) этого отсортированного набора:
Разумеется, вы скорее всего получите другой результат, но, поскольку данных в таблице немного, рано или поздно вы сможете получить и такой. :-) Использование функции FIRST_VALUEЭта оконная функция возвращает первое из упорядоченного набора значений. Теперь мы можем сделать все без подзапросов, выделив в окне набор рейсов для компании из текущей строки запроса с помощью предложения PARTITION BY и упорядочив его, как и в предыдущем примере, случайным образом в предложении ORDER BY:
Ключевое слово DISTINCT нужно здесь для того, чтобы не повторять одну и ту же компанию для каждого выполняемого ею рейса. Засада с LAST_VALUEКазалось бы, какая разница брать первое или последнее значение из случайным образом упорядоченного набора? Но давайте посмотрим, что мы получим, если в предыдущем запросе заменить FIRST_VALUE на LAST_VALUE:
Я приведу результаты только для id_comp = 1. Вы можете сами выполнить запрос, чтобы убедиться, что будут выводиться абсолютно все рейсы из таблицы Trip.
Что мы делаем в подобных случаях? Конечно, обращаемся к документации, а там мы читаем... Нет, постойте, сначала полный синтаксис:
Здесь А теперь читаем:
Внимание:
Диапазоном по умолчанию является RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. Т.е. окном является диапазон от текущей строки и неограниченно выше. Поскольку мы выбираем последнюю строку диапазона, то всегда будет выводиться текущая строка, как бы не сортировались строки. Т.е. сколько бы строк выше не оказалось при случайной сортировке. Потому и DISTINCT не помогает, т.к. все выводимые строки оказываются уникальными. Значит нам просто нужно явно (и правильно!) задать параметры окна, а именно, от текущей строки и неограниченно ниже, поскольку мы выбираем последнее значение:
Остался последний вопрос. Если мы не задавали параметры окна, почему у нас правильно отработал запрос с FIRST_VALUE? Ответ лежит на поверхности - потому что здесь значение по умолчанию нам подошло, хотя я и не нашел в документации, каким оно должно быть для FIRST_VALUE . Могу предположить, что тем же, что и для LAST_VALUE. |