Oracle cross apply: CROSS APPLY and OUTER APPLY in 12c

ПЕРЕКРЕСТНОЕ ПРИМЕНЕНИЕ и ВНЕШНЕЕ ПРИМЕНЕНИЕ в 12c

Привет,

Я узнал, что у нас есть ПЕРЕКРЕСТНОЕ ПРИМЕНЕНИЕ и ВНЕШНЕЕ ПРИМЕНЕНИЕ в 12c. Однако я вижу, что результаты одинаковы для CROSS APPLY и INNER JOIN, OUTER APPLY и LEFT/RIGHT OUTER JOIN.

Итак, когда INNER JOIN и LEFT/RIGHT OUTER JOIN являются стандартом ANSI и дают те же результаты, что и CROSS APPLY и OUTER APPLY, почему эти два метода были введены в 12c, и их цель одна и та же.

Синтаксис и использование понятны.

Не могли бы вы помочь в понимании цели.

С уважением,
Сунил Кумар Нути.
Amazing Fan of Concept KISS Series (Keep it Simple SQL) 🙂

Чтобы ответить на вопрос «почему они существуют», Алекс Кех, менеджер по программированию поставщиков .NET, сказал следующее:

Около десяти лет назад Microsoft представила новую технологию под названием Language Integrated Query (LINQ). LINQ позволял вам составить запрос один раз и заставить его работать с любым источником данных, включая Oracle DB. Для этого LINQ создает дерево выражений. Каждый провайдер источника данных берет дерево выражений и преобразует его в собственный SQL БД.

В большинстве случаев LINQ создает деревья выражений, которые можно преобразовать в стандартный SQL. Один из случаев, когда он генерирует ключевые слова CROSS APPLY. Это выражение поддерживается только SQL Server, но не Oracle.

Таким образом, мы поддерживаем CROSS APPLY для того, чтобы:

1) гарантировать, что клиенты LINQ могут использовать Oracle без возникновения ошибки, если этот SQL сгенерирован

2) помочь клиентам перенести свой SQL с SQL Server на Oracle

Так что на самом деле это просто для улучшения совместимости с другими системами. Если вы работаете над собственным приложением Oracle, вы, вероятно, можете их игнорировать.

Тем не менее, могут быть случаи, когда их использование может упростить понимание и/или ускорить выполнение запросов.

Например, рассмотрите следующий вопрос:

«Покажите мне двух самых высокооплачиваемых сотрудников, нанятых после 1 января 2007 г. в каждом отделе, а также сведения об отделе».

Теперь вы можете записать это с помощью объединения, например:

 выбрать * из (
выберите д.*, имя, фамилию, зарплату,
       row_number() over (раздел по d.department_id, порядок по описанию зарплаты) rn
от отдела кадров d
присоединиться к hr.employees e
на e.department_id = d.department_id
где e.hire_date >= date'2007-01-01'
)
где р <= 2
порядок по id_отдела, описанию зарплаты;
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID FIRST_NAME LAST_NAME SALARY RN
30 Закупки 114 1 700 Карен Кольменарес 2 500 1
50 Шиппинг 121 1 500 Кевин Мургос 5 800 1
50 Доставка 121 1 500 Энтони Кабрио 3 000 2
60 IT 103 1 400 Брюс Эрнст 6 000 1
60 IT 103 1400 Диана Лоренц 4200 2
80 Продажи 145 2 500 Джеральд Камбро 11 000 1
80 Продажи 145 2 500 Элени Злоткей 10 500 2
100 Финансы 108 1,700 Луис Попп 6,900 1
 

Или, используя кросс-применение, вместо этого вы можете сделать следующее:

 выберите d.*, имя, фамилия, зарплата
от отдела кадров d
перекрестное применение (
  выберите имя, фамилию, зарплату
  от hr. employees e
  где e.department_id = d.department_id
  и e.hire_date >= date'2007-01-01'
  заказать по e.salary desc
  получить только первые 2 строки
) е
заказ на 1, оклад по убыванию;
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID FIRST_NAME LAST_NAME ЗАРПЛАТА
30 Закупки 114 1 700 Карен Кольменарес 2 500
50 Доставка 121 1 500 Кевин Мургос 5 800
50 Доставка 121 1 500 Энтони Кабрио 3 000
60 IT 103 1400 Брюс Эрнст 6000
60 IT 103 1400 Диана Лоренц 4200
80 Продажи 145 2 500 Джеральд Камбро 11 000
80 Продажи 145 2 500 Элени Злоткей 10 500
100 Финансы 108 1,700 Луис Попп 6,900
 

Лично я думаю, что запрос перекрестного применения немного легче понять. Но это сводится к личным предпочтениям и знаниям перекрестного применения! 😉

См. также:

https://explainextended.com/2009/07/16/inner-join-vs-cross-apply/
https://oracle-base.com/articles/12c/lateral- inline-views-cross-apply-and-outer-apply-joins-12cr1#cross-apply-join

sql server - есть ли альтернатива ВНЕШНЕМУ ПРИМЕНЕНИЮ в Oracle?

спросил

Изменено
6 лет, 1 месяц назад

Просмотрено
12 тысяч раз

В следующем примере я передаю tbA. ID в запрос tbC . В этом случае я использовал оператор OUTER APPLY для SqlServer.

 ВЫБОР
  ...
FROM (SELECT ID FROM TableA...) tbA
ВНЕШНЕЕ ПРИМЕНЕНИЕ (ВЫБРАТЬ... ИЗ TableB tbB, ГДЕ tbA.ID = tbB.ID) tbC
...
 

В Oracle нет оператора OUTER APPLY. Итак, как я могу передать значение (tbA.ID) из левого запроса в правый запрос (tbC) соединения без изменения структуры моего запроса?

Есть ли альтернатива ВНЕШНЕМУ ПРИМЕНЕНИЮ в Oracle?

  • sql-сервер
  • оракул
  • внешнее применение

5

SQL Servers внешнее применение аналогично стандартам SQL боковой . Oracle поддерживает lateral , начиная с 12c(*).

Вместо external apply вы должны использовать left join lateral в стандартном SQL или cross join lateral , если вы хотите опустить предложения ON / USING .

Сноска:
(*) до версии 12c Oracle «не поддерживал» lateral при включении события трассировки. См. https://jonathanlewis.wordpress.com/2011/01/31/ansi-outer/

3

Изменить в соответствии с комментариями:

В Oracle 12 OUTER APPLY поддерживается (вероятно, как часть стандарта SQL). Поскольку ваш SQL сгенерирован Entity Framework, все, что вам нужно сделать, это подключиться к Oracle и посмотреть, как выглядит результат сгенерированного запроса. Я чувствую, что ваш вопрос основан на страхе: «Как это будет работать в Oracle?». Запустите код и посмотрите.

В остальном встроенные запросы Oracle работают точно так же, как таблицы. Ваш вопрос, "
есть ли альтернативы...?»
- да, см. ниже:

 ВЫБОР
  ...
ОТ
    (SELECT ID FROM TableA...) tbA левое соединение
    (ВЫБЕРИТЕ ID ИЗ Таблицы B...) tbB On tbA.ID = tbB.ID
 ...
 

6

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя адрес электронной почты и пароль

Опубликовать как гость

Электронная почта

Требуется, но никогда не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Нажимая «Опубликовать свой ответ», вы соглашаетесь с нашими условиями обслуживания и подтверждаете, что прочитали и поняли нашу политику конфиденциальности и кодекс поведения.