|
|
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
AlexFF__|Так что извини, но мне кажется, что ты путаешь не только ТС Я, как бы, живой и могу сам ответить. Я понял, что в целом всегда следует придерживаться семантики. А чтобы делать что-то нестандартно, то нужно хорошо знать, как устроено «под капотом». ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 11:14 |
|
||
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
andrey_anonymous... То, что значение выражения не определено для t1.id = 2 в рамках трехзначной логики означает, что выражение не истинно и строка во множество, определенное предикатом, не входит. Таким образом, тезис, о том, что SQL-запрос "ДОЛЖЕН давать ошибку" в указанной ситуации - на самом деле ложен... В целом - браво, и красиво соответствует определению операции сравнения в sql Но - andrey_anonymous... (ну нет в ЯЗЫКЕ SQL средств для работы с исключительными ситуациями)... ... это не совсем (совсем не) так. sql-99 явно определяет семантику исключительных ситуаций для вычислений. В частности, ISO/IEC 9075-2:1999 (E) 6.17 <numeric value function> <cardinality expression> ::= CARDINALITY <left paren> <collection value expression> <right paren> <absolute value expression> ::= ABS <left paren> <numeric value expression> <right paren> <modulus expression> ::= MOD <left paren> <numeric value expression dividend> <comma> <numeric value expression divisor><right paren> <numeric value expression dividend> ::= <numeric value expression> <numeric value expression divisor> ::= <numeric value expression> ... далее - ... 10) If <modulus expression> is specified, then let N be the value of the immediately contained <numeric value expression dividend> and let M be the value of the immediately contained <numeric value expression divisor>. Case: a) If either N or M is the null value, then the result is the null value. b) If M is zero, then an exception condition is raised: data exception — division by zero. c) Otherwise, the result is the unique nonnegative exact numeric value R with scale 0 (zero) such that all of the following are true: i) R has the same sign as N. ii) The absolute value of R is less than the absolute value of M. iii) N = M * K + R for some exact numeric value K with scale 0 (zero). andrey_anonymous... Беспокоить может лишь нестабильность результата (то набор данных, то аварийное завершение в зависимости от положения звезд на небе) - и подобное поведение (if any) мы смело запишем в недостатки конкретной реализации. ... ну да. Вот это - результат (состояние курсора при возникновении run-time error) как раз и оставлено на взгляд implementation. Что как-бы обессмысливает теоретическую красоту интертрепации результата логического выражения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 11:39 |
|
||
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
andrey_anonymousDimitry Sibiryakovпропущено... В данном случае она "предшествует" чисто синтаксически. То есть выделенное предложение говорит, что WHERE в тексте запроса стоит после FROM и ничего больше. Коллеги, это уже детский сад. Соломон показал, что оно: - так работает - так реализовано - так описано в стандарте То, что в частных конкретных случаях (включая innser join) фильтры могут без нарушения логики быть протолкнуты непосредственно к rowsource - не меняет принципа. Логически предикаты where применяются к множеству, определенному from. Точка. Если начинающий программист будет воспринимать это именно так - не допустит дурацких ошибок, которыми бывает пересыпан код начинающих, не осознающих разницы.Все дело лишь в точности формулировок. 1. Если утверждать что where применяется после, то некоторые могут захотеть писать Код: plsql 1. 2. 3. Можно сказать, что это надо быть совсем чайником. Ну так если б ТС умел читать планы - у него и вопроса бы не возникло. 2. Формулировки, что предикаты "могут быть протолкнуты" или "оптимизатор может решить" верны в теории. На практике, предикаты по внешней таблице никогда не будут применены до, предикаты исключительно по внутренней всегда будут применены до. Полагаю тут как не играйся на двух таблицах хоть с предикатами по UDF + associate statistics + отключение всех трансформаций + что угодно - внутренний rowsource будет отфильтрован до соединения когда это возможно. 3. Ну и рассказывать про порядок применения на основании expand_sql_text и обычных (не коррелированных, не non-mergeable) inline view - это уж совсем некорректно. Тем более final query в 10053 выглядит несколько иначе. Так что просто надо разделять теорию и практику. SY, спасибо за цитату. Пропустил файл "5WD-02-Foundation-2003-09.pdf" для стандарта SQL:2003. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 11:59 |
|
||
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop...Все дело лишь в точности формулировок. 1. Если утверждать что where применяется после, то некоторые могут захотеть писать Код: plsql 1. 2. 3. Можно сказать, что это надо быть совсем чайником.... дело, имхо, в другом. Давайте все же внешнее соединение... Вот тут - Код: plsql 1. 2. надо полагать - чайником, т.к. из outer превратится в inner а тут? Код: plsql 1. 2. это вообще нельзя выписать без union в традиционном синтаксисе, при совершенно ясной семантике. т.е. - от перемены мест чайник кипит при разных температурах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 12:32 |
|
||
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
boobydbms_photoshop...Все дело лишь в точности формулировок. 1. Если утверждать что where применяется после, то некоторые могут захотеть писать Код: plsql 1. 2. 3. Можно сказать, что это надо быть совсем чайником.... дело, имхо, в другом. Давайте все же внешнее соединение... Вот тут - Код: plsql 1. 2. надо полагать - чайником, т.к. из outer превратится в inner а тут? Код: plsql 1. 2. это вообще нельзя выписать без union в традиционном синтаксисе, при совершенно ясной семантике. т.е. - от перемены мест чайник кипит при разных температурах.Если обсуждать мышление чайников и абстрактные запросы в вакууме можно вообще далеко зайти. Так что, желательно хоть немного понимать что требуется получить. В первом случае, очевидно, отсутствие плюса в "t2.status > 0" делает этот предикат post join. Если вспользоваться case намекая на "неразрывность условий", то получим соответствующие ошибки 11g Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 12c Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. Во втором случае, если таки цель все сделать предикатами соединения (то есть догадавшись поставить (+)), получим 11g, 12c Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. или применив вышеупомянутый прием с case 11g, 12c Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 13:25 |
|
||
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopили применив вышеупомянутый прием с case Ну вот и expand пригодился. dbms_photoshopНу и рассказывать про порядок применения на основании expand_sql_text и обычных (не коррелированных, не non-mergeable) inline view - это уж совсем некорректно. Тем более final query в 10053 выглядит несколько иначе. Конечно иначе. Но экспанд, помимо прочего, показывает как выглядит SQL пользователя который в общем случае написан на ANSI SQL перeведенный на нативный Oracle SQL. И показывал я его только с этой точки зрения, т.е. с точки зрения логики а не имплементации - как ANSI SQL с отдельными ON и WHERE транслируется в Oracle SQL где есть тoлько WHERE при этом coблюдая логику результата. Ну а дальше, как я и говорил, колдует оптитизатор. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 13:50 |
|
||
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop1. Если утверждать что where применяется после, то некоторые могут захотеть писать Не "после", а "к" - однако разница dbms_photoshop2. Формулировки, что предикаты "могут быть протолкнуты" или "оптимизатор может решить" верны в теории. На практике, предикаты по внешней таблице никогда не будут применены до, предикаты исключительно по внутренней всегда будут применены до. Никогда не говори "никогда": Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 14:50 |
|
||
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop, ок, за case спасибо. что касательно pre и post нет в стандарте sql ни pre ни post есть from clause, joined table, join condition есть where clause, которая по определению логически выполняется после from clause, но ни pre-condition, ни post-condition просто нет. о pre и post отдельно от join condition можно говорить только применительно к алгоритмам работы конкретного оптимизатора. Какое условие каким окажется - pre, формирующим derived table, к которой потом будет применяться join condition или уйдет на фазу post ("истинного" фильтра) - нельзя в общем предсказать даже видя конкретную запись запроса, т.к. it depends и от физики (наличия подходящих индексов, например или известных constraints) и от деталей устройства предиката и даже от фактических статистик, известных системе и оценки стоимости вычисления предиката. Для простых случаев - наверно достаточно надежно можно, в общем - нет. Так или иначе, перенос чего-то в pre или наоборот - ранний join путем слияния явно выписанной derived table - оправдывается набором трансформаций/преобразований, который оптимизатор считает допустимыми, не меняющими логически результата запроса. Все это здорово и правдоподобно, до тех пор, пока не примешивается data exception-s, которые подвешивают вопрос об эквивалентности результата. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 15:11 |
|
||
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
andrey_anonymousНикогда не говори "никогда"Зачет. :) Пока шел на работу и думал про прядок еще возникла мысль про экзадату, когда писал ответ - вылетело из головы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 15:22 |
|
||
|
Где лучше указывать условие, в join или where?
|
|||
|---|---|---|---|
|
#18+
boobyок, за case спасибо.Если глянуть в final query 10053, то думаю там можно увидеть lateral и соотвественно применив lateral/outer apply получить желаемое в 12с без всяких трюков. В 11g таки необходим case. Необходимость case вообще снижается от версии к версии. То есть, подмножество запросов когда возникает ORA-01719 на 11g меньше чем на 10g, а на 12с меньше чем на 11g. И если в некоторых случаях необходимость case сомнительна, то в некоторых других - таки обязательна, иначе непонятно как трактовать одно из условий - фильтр или соединение. Я вообще написал "работу" по соединениям примерно на 20 страниц - думаю в ближайший месяц опубликую. Возможно кому-то будет полезно и/или интересно. boobyчто касательно pre и postpre и post берут свое начало из уже упомянутой ноты "Guidelines for Using Outer Join Syntax (Doc ID 14736.1)". Насколько помню первым начал применять эту терминологию на этом форуме Я и ёжик. И она имеет отношение именно к Oracle native syntax и по понятным причинам не упоминается в стандарте. Тут для полноты картины стоит отменить, что non-ANSI outer join поддерживал и MSSQL с давних времен. Только там он называется " old-style, non-SQL-92-style join " (символы =* и *=). Что еще раз подчеркивает то, что подобным образом пишут соединения не так как предписывает стандарт. Майкрософт достаточно жестко выпиливает этот синтаксис и на последних версиях он сначала выдавал предупреждение, а потом и вовсе перестал поддерживаться. Outer join operators *= and =* are not supported in 90 or later compatibility modes В других ветках форума можно найти тоже достаточно много упоминаний про pre/post join, но там они по большей части этот концепт распиарен участником Добрый Э - Эх и его клонами. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2016, 15:48 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=39319487&tid=1887334]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
179ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
32ms |
get tp. blocked users: |
1ms |
| others: | 213ms |
| total: | 462ms |

| 0 / 0 |
