ОБЪЕДИНЕНИЕ ВСЕХ запросов, использующих с разрывами операторов

#sql #oracle

#sql #Oracle

Вопрос:

Я написал запрос с использованием оператора with и объединения all. Но я не привык писать сложные запросы. Он продолжает прерываться при объединении all. Пожалуйста, укажите мне, где это неправильно?

 WITH t1 (source, target) AS (
SELECT 
t1.study_name,
t1.site_id

FROM  iv_p_mv


UNION ALL


SELECT 
t2.study_name,
t2.site_id
FROM  iv_p_mv as t2 left outer join t1 on t1.study_name = t2.study_name

)

SELECT 
study_name,
site_id
FROM  t1 
 

Ошибка:

Ссылка t1 не найдена.

Комментарии:

1. Пожалуйста, объясните, что вы хотите сделать. Возможно, вам нужен рекурсивный CTE.

2. @Gordon Я просто ищу способ исправить этот запрос, чтобы получить некоторые результаты. Просто эта проблема с t1 в качестве ссылочной ошибки.

3. удалите как FROM iv_p_mv as t2 так, чтобы FROM iv_p_mv t2 и повторите попытку

4. не могли бы вы, пожалуйста, объяснить, какая логика стоит за этим? какова ваша цель здесь?

Ответ №1:

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

В этом случае, скорее всего, это будет указывать на четвертую строку (та же ошибка существует в третьей строке). В якорном элементе рекурсивного запроса (имеется в виду: первая часть) вы select t1.study_name, t1.site_id from iv_p_mv . t1 В этом контексте нет — вы не использовали псевдоним таблицы (или материализованного представления) как t1 . (Также было бы ужасной идеей использовать псевдоним таким образом — t1 это имя представления, которое вы создаете в WITH предложении, также не используйте его где-нибудь в WITH предложении.)

Вам не нужен псевдоним там — вы можете просто выбрать study_name, site_id в этой части запроса.

 WITH t1 (source, target) AS (
SELECT 
t1.study_name,              -- Remove "t1."
t1.site_id                  -- Remove "t1."

FROM  iv_p_mv


UNION ALL
 

После того, как вы исправите это, вы обнаружите другую ошибку, на которую уже указывалось: в Oracle вы не можете использовать ключевое as слово перед псевдонимом таблицы (раньше t2 в вашем коде). При необходимости ключевое слово можно использовать as перед псевдонимами столбцов, но не перед псевдонимами таблиц и представлений.

Комментарии:

1. Я все еще получаю ссылку t1, которая не найдена.

2. @KSp — я пропустил пару других ошибок в вашем коде; но если вы исправили то, что я вам сказал, то вы не должны получать сообщение об ошибке «ссылка t1 не найдена», если только ваш код не соответствует тому, который вы опубликовали. Дополнительные ошибки: во-первых, в with предложении вы говорите, что столбцы будут переименованы от study_name, site_id до source, target . Непонятно, почему вы это делаете, но если вы это сделаете, вы не сможете ссылаться t1.study_name , например, на рекурсивный член — это должно быть t1.source . Другая ошибка заключается в том, что внешнее соединение в рекурсивном предложении WITH не разрешено.

3. если я помещу t1.source, где я буду получать study_name?

4. @KSp — Почему вы меняете имена с «study_name» и «site_id» на «source» и «target» в первую очередь? Лучшее «исправление» в вашем коде — это изменить их на «study_name» и «site_id» в верхней части предложения WITH — нигде не используйте «источник» и «цель». (Или, если это требуется, укажите их в качестве псевдонимов в окончательном выборе после рекурсивного предложения WITH .)

Ответ №2:

Просто из любопытства. Это то, что вам нужно?

 WITH source AS (
    SELECT t1.study_name, t1.site_id 
    FROM iv_p_mv t1),
    target as (
    SELECT t2.study_name, t2.site_id
    FROM iv_p_mv t2 LEFT OUTER JOIN source s ON s.study_name = t2.study_name
    union all 
    SELECT s.study_name, s.site_id
    FROM source s)   
SELECT
    study_name,
    site_id
FROM target;
 

@KSp * Я вижу, что вы приняли это как ответ, но если вам нужен рекурсивный запрос, он должен выглядеть более похоже (см. Ответ и комментарии от @mathguy)

 WITH t1 (source, target) AS (
    SELECT study_name   source,
           site_id      target
    FROM iv_p_mv
    UNION ALL
    SELECT t2.study_name,
           t2.site_id
    FROM iv_p_mv t2, t1
    WHERE t1.source = t2.study_name ( )
)
SELECT source, target FROM t1
 

Комментарии:

1. Скорее всего, нет. OP написал рекурсивный запрос (рекурсивное WITH предложение). Мы не знаем, что OP действительно хотел, чтобы запрос выполнял, но формально в его коде были две (незначительные) синтаксические ошибки, в противном случае это был совершенно корректный рекурсивный запрос. Судя по вашему переписыванию запроса, я готов поспорить, что вы даже не знакомы с концепцией «рекурсивный запрос». Я ошибаюсь?

2. … как выясняется, при ближайшем рассмотрении обнаруживаются дополнительные ошибки в исходном коде, но все они по-прежнему связаны с концепцией «рекурсивного предложения WITH». Я подробно описал дополнительные ошибки в комментарии к своему собственному ответу (в ответ на последующие действия из OP).

3. @mathguy просто любопытно 😉 ; Я понял ответ KSp выше как простое объединение all, с запросом ^ Я просто ищу способ исправить этот запрос, чтобы получить некоторые результаты. Просто эта проблема с t1 в качестве ссылочной ошибки. не нужно злиться..

4. Не уверен, почему вы думаете, что я «злюсь» — это неподдерживаемые предположения с вашей стороны. (Я, на самом деле, совсем не злюсь). Итак, вы знакомы с «рекурсивным предложением WITH»? Если вы скажете «да», то я не понимаю, как вы переходите от попытки OP к вашему коду. Если вы скажете «нет», это все — нет необходимости обсуждать дальше.