ПроблемойSQL - Отношения между подзапросом и внешней таблицей
мне нужно, чтобы лучше понять правила о том, когда я могу ссылаться на внешнюю таблице в подзапросе и когда (и почему), что является неуместной запрос. Я обнаружил дублирование в запросе Oracle SQL, который я пытаюсь реорганизовать, но у меня возникают проблемы при попытке превратить мою ссылочную таблицу в сгруппированный subQuery.
Следующее утверждение работает надлежащим образом:
SELECT t1.*
FROM table1 t1,
INNER JOIN table2 t2
on t1.id = t2.id
and t2.date = (SELECT max(date)
FROM table2
WHERE id = t1.id) --This subquery has access to t1
К сожалению table2 иногда имеет повторяющиеся записи, поэтому мне нужно агрегировать t2 первым, прежде чем я присоединяюсь к его t1. Однако, когда я пытаюсь обернуть его в подзапрос, чтобы выполнить эту операцию, внезапно механизм SQL больше не сможет распознать внешнюю таблицу.
SELECT t1.*
FROM table1 t1,
INNER JOIN (SELECT *
FROM table2 t2
WHERE t1.id = t2.id --This loses access to t1
and t2.date = (SELECT max(date)
FROM table2
WHERE id = t1.id)) sub on t1.id = sub.id
--Subquery loses access to t1
Я знаю, что это принципиально разные запросы Я прошу компилятор поставить вместе, но я не вижу, почему один будет работать, но не другой.
Я знаю, что я могу дублировать ссылки в таблице в моем подзапросе и эффективно отделять мой подзапрос от внешней таблицы, но это кажется действительно уродливым способом выполнения этой задачи (что со всем дублированием кода и обработки).
Полезные Ссылки
Я нашел это фантастическое описание порядка, в котором положения выполняются в SQL Server: (INNER JOIN ON vs WHERE clause). Я использую Oracle, но я думаю, что это будет стандартно по всем направлениям. Существует четкий порядок определения предложения (с первым FROM), поэтому я думаю, что любое предложение, появившееся дальше в списке, будет иметь доступ ко всей ранее обработанной информации. Я могу только предположить, что мой второй запрос каким-то образом изменяет порядок, чтобы мой подзапрос оценивался слишком рано?
Кроме того, я нашел подобный вопрос задал (Referencing outer query's tables in a subquery ), но в то время как вход был хорошим, они никогда не объяснили, почему он не может делать то, что он делает, и просто дал альтернативные решения своей проблемы. Я пробовал свои альтернативные решения, но это вызывает другие проблемы. А именно, этот подзапрос с ссылкой на дату является фундаментальным для всей операции, поэтому я не могу избавиться от нее.
Вопросы
Я хочу, чтобы понять, что я сделал здесь ... Почему мой первоначальный подзапрос увидеть внешнюю таблицу, но не после того, как я обернуть весь заявление в подзапросе ?
Сказанное, если то, что я пытаюсь сделать, не может быть сделано, каков наилучший способ рефакторинга первого запроса для устранения дублирования? Должен ли я дважды ссылаться на таблицу1 (со всем необходимым дублированием)? Или есть (возможно) лучший способ решить эту проблему?
Заранее благодарен!
------ EDIT ------
Как некоторые уже догадались эти запросы выше, а не на самом деле запрос я рефакторинга, но пример проблемы, я работает в , Задача, с которой я работаю, намного сложнее, поэтому я не решаюсь опубликовать ее здесь, поскольку я боюсь, что это заставит людей отследить.
------ ОБНОВЛЕНИЕ ------
Так что я побежал это разработчик собрата, и он был одним из возможных объяснений того, почему мой подзапрос теряет доступ к t1. Поскольку я заключу этот подзапрос в круглую скобку, он считает, что этот подзапрос оценивается до того, как будет оценена моя таблица t1. Это определенно объясняет ошибку «ORA-00904:« t1 ».« Id »: неверный идентификатор, который я получил. Это также предполагает, что, подобно арифметическому порядку операций, добавление parens в оператор дает ему приоритет в определенных оценках клаузулы. Я все равно буду любить эксперта, чтобы взвесить, если они согласятся/не согласны, что является логичным объяснением того, что я вижу здесь.
Выведенная таблица не может быть скоррелирована. Он должен стоять один. Хотя вы можете присоединиться к нему. вы можете использовать 'APPLY', где вам нужна какая-то коррелированная производная таблица. –
Martin .... искренне, спасибо! Основываясь на вашем комментарии, я смог сделать небольшое дополнительное исследование и обнаружил, что мой запрос на самом деле не извлекает данные, как я изначально думал. Также ваш совет по применению Apply кажется очень применимым (хотя для меня синтаксис немного отличается, поскольку я использую Oracle). Очень ценю совет - на самом деле, если вы представите его в качестве ответа, я буду отмечать его как правильный. – DanK