#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 к вашему коду. Если вы скажете «нет», это все — нет необходимости обсуждать дальше.