Вопрос

Я знаю, что Oracle RDMS не может объединить представление, который имеет набор оператора в нем. Я хочу знать, почему это.

Например, это:

SELECT u.*
FROM
 (
  SELECT a.a1    A,
        a.a2    B
   FROM tab_a a
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b
)     u,
tab_p p
WHERE p.a = u.a

может быть преобразован в это:

SELECT *
FROM
 (
  SELECT a.a1    A,
         a.a2    B
    FROM tab_a a,
         tab_p p
   WHERE p.a = a.a1
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b,
         tab_p p
   WHERE p.a = b.b1
)

Эти два запроса эквивалентны, верно? [Отредактировано

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

Решение

Преобразование, которое вы описываете в вашем отредактированном вопросе, кажется действительным для меня.

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

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

Итак, не то, чтобы он «не могу», обязательно; Это просто еще нет.

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

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


Ранее оба запроса использовали SELECT *, нет псевдонима таблицы в любом из них.

Нет, эти запросы не эквивалентны.

Первый будет возвращать столбцы с обоих полученных таблиц (Union'D astrue) и tab_p стол. Второй запрос будет возвращать только значения из производного таблицы (Union'd authoble), а не столбцы из tab_p стол. Это более очевидно, если вы заменяете псевдонимы таблицы на месте SELECT *:

Первый запрос:

SELECT u.*, p.*
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u,
       tab_p p
 WHERE p.a = u.a

Второй запрос:

SELECT x.*
 FROM (SELECT a.a1    A,
              a.a2    B
         FROM tab_a a,
              tab_p p
        WHERE p.a = a.a
       UNION ALL
       SELECT b.b1    A,
              b.b2    B
         FROM tab_b b,
              tab_p p
        WHERE p.a = b.a) x

Нет tab_p Столбцы в пункте выбора внутреннего запроса, для внешнего запроса, чтобы обеспечить в конечных результатах.

Этот:

SELECT *
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u
  JOIN tab_p p ON p.a = u.a

.. и эквивалентно первым запросу. Он использует синтаксис соединения ANSI-92 VS Syntax ANSI-89, используемый в первом запросе.

Они не эквивалентны. Второй запрос потерпит неудачу, как u не определен.

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