Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Почему такое поведение запроса / 21 сообщений из 21, страница 1 из 1
07.04.2020, 11:01
    #39944498
nxx
nxx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
select 
      (
        case 
          when x like '1%' or 
            '111' = all (
              select ''
              from dual
              where 1=0
            )
          then '+++'  
          else '---'
        end        
      )
    from (
      select '999' as x
      from dual
    ) b



выдает +++
хотя оба условия false
...
Рейтинг: 0 / 0
07.04.2020, 11:20
    #39944501
nxx
nxx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
кажись понял, это такая фича
но не понятно из каких соображений так сделали
...
Рейтинг: 0 / 0
07.04.2020, 11:47
    #39944509
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
nxx,

X=ALL(select Y from ...) трансформируется в NOT EXISTS(select 0 from ... where ... and lnnvl(X=Y))
...
Рейтинг: 0 / 0
07.04.2020, 12:04
    #39944515
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
nxx,
такое соглашение принято на уровне общего стандарта sql с самого начала.
И, например, если где-то оно не выполняется, то это точно баг оптимизатора - он выбрал недопустимую трансформацию запроса.

для многострочных подзапросов есть модификаторы оператора сравнения ALL и ANY
операции могут быть:
< ANY, <= ANY, = ANY >= ANY, > ANY, != ANY
или
< ALL, <= ALL, = ALL >= ALL, > ALL, != ALL

Для первой группы операций принято соглашение, что если подзапрос не возвращает строк, то результат False
Для второго набора наоборот, если строк в подзапросе нет, то результат True

В этих соглашениях есть дополнительный момент - в любой строке подзапроса, если строки есть, может оказаться Null
Тогда Any должен такую строку просто игнорировать, а All при наличии Null - немедленно выдать False

В этом смысле IN работает как ANY, а NOT IN как ALL
...
Рейтинг: 0 / 0
07.04.2020, 12:07
    #39944518
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
nxx
кажись понял, это такая фича
op ALLIf all of these comparisons return TRUE, or the subquery on the right side returns no rows, op ALL returns TRUE . Otherwise, the return value is UNKNOWN.
...
Рейтинг: 0 / 0
07.04.2020, 12:35
    #39944529
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
nxx
кажись понял, это такая фича
но не понятно из каких соображений так сделали
Склероз это страшное дело.
почему так ?
Видимо ничего из 4-х стрниц в памяти не отложилось.

Поведение определяется не какими-то стандартами SQL, а здравым смыслом.
Код: plsql
1.
2.
3.
4.
5.
  def eq_all[T](v: T, l: List[T]) = l.map(_ == v).foldLeft(true)(_ & _)
  def eq_any[T](v: T, l: List[T]) = l.map(_ == v).foldLeft(false)(_ | _)

  for (i <- Set(2,4); j <- Set(List(2, 4), List(2), List()))
    println(i, j, eq_all(i, j), eq_any(i, j))

eq_all имитирует ALL и, соответственно, eq_any - ANY.
Код: plsql
1.
2.
3.
4.
5.
6.
(2,List(2, 4),false,true)
(2,List(2),true,true)
(2,List(),true,false)
(4,List(2, 4),false,true)
(4,List(2),false,false)
(4,List(),true,false)
...
Рейтинг: 0 / 0
07.04.2020, 12:36
    #39944531
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
-2-
nxx
кажись понял, это такая фича
op ALLIf all of these comparisons return TRUE, or the subquery on the right side returns no rows, op ALL returns TRUE . Otherwise, the return value is UNKNOWN.
Тогда тут должно быть пусто?
Код: plsql
1.
select * from dual where not 1 = all(1, 2)
...
Рейтинг: 0 / 0
07.04.2020, 12:39
    #39944536
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
Кобанчег
...
Поведение определяется не какими-то стандартами SQL, а здравым смыслом.
...

Это пять.
Ты мой кумир ...
...
Рейтинг: 0 / 0
07.04.2020, 13:10
    #39944543
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
booby,

Для тебя стало откровением что ANY/ALL это более общее понятие и они имеют отношение не только к SQL?
При этом механизм работы везде один и тот же.

Твои фантазии про игнонирование строк с NULL и прочее основаны вероятно только на узости кругозора и богатом воображении.
Более полезно знать что возвращает expr AND UNKNOWN или expr OR UNKNOWN.

Можешь ознкомиться с ANY/ALL в Haskell, Python, etc.
...
Рейтинг: 0 / 0
07.04.2020, 13:27
    #39944547
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
Кобанчег,

ширизна кругозора и понимание увиденного - не синонимы.

ANY/ALL - это вообще не понятия, а модификаторы операций сравнения для их применения к множествам значений.
А вот их работа опирается на понятия и понимание логики предикатов.
...
Лучше бы ты на свой последний вопрос ответил.
Или здравым смыслом объяснил работу ALL, используя AND UNKNOWN


И это, уж не сердись, быть кумиром - это не обязательно то, что в твоей воле.
Терпи и радуйся.
...
Рейтинг: 0 / 0
07.04.2020, 13:36
    #39944549
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
Кобанчег
Тогда тут должно быть пусто?
Код: plsql
1.
select * from dual where not 1 = all(1, 2)

Я бы тоже трактовал, что UNKNOWN относится ко всему предложению, а не только к после or the subquery.op ALLIf all of these comparisons return TRUE, or the subquery on the right side returns no rows, op ALL returns TRUE . Otherwise, the return value is UNKNOWN. Индусы добавляли второе предложение в более поздней документации из благих побуждений, хотели пояснить нюансы и не сломать, "что работает". Но вышло как всегда.
...
Рейтинг: 0 / 0
07.04.2020, 13:43
    #39944555
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
booby
Или здравым смыслом объяснил работу ALL, используя AND UNKNOWN
Объясняю.
Изначально результат инициализируется TRUE. Потом выполняется поэлементное выполнение операции и объединение результатов через AND.
Напрмиер, если для первого элемента результат TRUE, а для второго UNKNOWN из-за NULL, то итог UNKNOWN.
Код: plsql
1.
2.
3.
4.
5.
select case when     1 > all(0, null) then 'true'
            when not 1 > all(0, null) then 'false'
            else 'unknown'
       end x
  from dual


Сравни результат с (TRUE AND UNKNOWN AND FALSE).
Код: plsql
1.
2.
3.
4.
5.
select case when     1 > all(0, null, 2) then 'true'
            when not 1 > all(0, null, 2) then 'false'
            else 'unknown'
       end x
  from dual



Вот это неверно:
booby
All при наличии Null - немедленно выдать False
...
Рейтинг: 0 / 0
07.04.2020, 13:54
    #39944556
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
Кобанчег,

авторВот это неверно:
booby

All при наличии Null - немедленно выдать False

Это верно .
Просто ты не понимаешь, как работает not.
А работает он так, как раскрывается.
...
Рейтинг: 0 / 0
07.04.2020, 13:58
    #39944557
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
Кобанчег,
кстати,

авторОбъясняю.
Изначально результат инициализируется TRUE.

это центральный момент для All
Так в чём здравый смысл утверждения, что сравниваемое значение равно любому из пустого множества?
...
Рейтинг: 0 / 0
07.04.2020, 14:36
    #39944562
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
booby
Так в чём здравый смысл
Здравый смысл в том, что есть инициализация начальным значением и последующее поэлементное вычисление логического выражения с объединением результатов.
Принцип уже был изображен в виде кода ранее этой теме.
Если кого-то смущает инициализация ALL значением TRUE это лишь их персональная проблема.
Что примечательно подобные люди встречаются только среди эскуэльщиков и их довольно много.
Вот мне ни разу не попадалось чтоб программист на Haskell жаловался что ALL на пустом множестве возвращает истину.

Последний контрольный.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SQL> select *
  2    from dual
  3   where not (1 > all(0, null, null, null, null, null, null));

no rows selected

SQL>
SQL> select *
  2    from dual
  3   where not (1 > all(0, null, null, null, null, 2, null));

D
-
X

Видишь как во втором случае выбрало строку? Значешь почему?
Потому что под конец попалось двоечка которая привела к тому что результат стал FALSE.
До этой двоечки надо было дойти, ничего немедленно не выдавалось при первом попавшемся NULL.

Теперь смотрим на первый пример. Чот там у нас? Ничего не выбрано. Хм... может быть это потому что результат UNKNOWN.
Так кто там куда немедленно выедает FALSE?

Вопросы риторические. Если и после этого не дошло, то я пожалуй пас.
...
Рейтинг: 0 / 0
07.04.2020, 14:43
    #39944563
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
Кобанчег,

пас ты сделал заявлением о том, что "программист на Haskel" не жалуется.
То есть почему это так - ты не знаешь.

Про все остальное ответ был дан - not работает так, как раскрывается.
...
Рейтинг: 0 / 0
07.04.2020, 14:57
    #39944565
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
кстати, вот это:
booby
... сравниваемое значение равно любому из пустого множества?

как раз ошибочное утверждение, на что ты не обратил внимания.

Правильная формулировка такая:
сравниваемое значение равно всем значениям из пустого множества.
...
Рейтинг: 0 / 0
07.04.2020, 17:10
    #39944600
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
booby
сравниваемое значение равно всем значениям из пустого множества.

Элемент равен множеству.
Угу.
Хорошая трава.
...
Рейтинг: 0 / 0
07.04.2020, 17:55
    #39944615
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
andrey_anonymous
booby
сравниваемое значение равно всем значениям из пустого множества.

Элемент равен множеству.
Угу.
Хорошая трава.

желательно, чтобы размер завирания и плетения словесами имел распознаваемые границы.
Ну, годится и в рамках "здравого смысла", к которому тут уже иные апеллировали,
с опознаваемыми метками по способам его интертрепации.
...
Рейтинг: 0 / 0
25.04.2020, 07:14
    #39951260
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
Всё-таки мне мешает незавершенность этого разговора.
(Я хотел высказаться после "следующего" высказывания, которого не последовало)
После обмена первыми репликами весь дальнейший разговор получился позиционно
перевернутым, что меня забавило, но потребность как-то разумно завершить его осталась.

Вот это утверждение Кобанчег-а формально верное:
Кобанчег
...
Вот это неверно:
booby
All при наличии Null - немедленно выдать False

Как, в этом же смысле, верны последующие попытки обоснования неверности моего
утверждения на основе формально определенной в стандарте sql трехзначной логики true/false/unknown.
Между тем, сделал я его вполне сознательно, и как раз на основе здравого смысла .

Формально верным было бы, если бы я сказал так:
Условия преждевременного выхода из цикла для ALL/ANY не отличаются (одинаковые)
для двухзначной и трёхзначной логики: по false в первом случае и true во втором.

В обоих случаях достижение соответствующего значения не может далее изменить
логического значения предиката и вычисление можно остановить.

Почему я сказал именно то, что сказал:
- стандарт sql для предиката с ALL/ANY определяет возможность получения все трех
логических значений True/False/Unknown - далее T/F/U
- отрицание NOT U -> U, а NOT F -> T что для ALL формально приводит к логической ошибке при досрочном выходе из цикла по первому U, встретившемуся до F в результате вычисления.
- Oracle использует (может использовать) для ALL трансформацию в NOT EXISTS(...), для ANY в EXISTS(...)
- стандарт sql оба оператора EXISTS/ NOTEXISTS определяет как принимающие лишь два
логические значения T/F, оба они не могут возвращать U

Тогда: Либо
а) Oracle использует принципиально некорректное, формально ошибочное преобразование предиката,
способного получать три значения, в предикат, способный принимать лишь два из них.
Либо
б) используемое преобразование фактически корректно и тогда (смотрим первый ответ в топике от xtender)
выход из not Exists со значением Not T -> F по первому получению U, преобразованному в T через lnnvl, тоже корректен.

Что полностью эквиваленто сделанному мной утверждению, и как раз не на основе стандарта, а основе "здравого смысла".
"Здравость" же, имхо, здесь заключается в том, что каким бы ни было значение предиката
с ALL/ANY - T/F или U, оно не меняет результата работы общего фильтра в том смысле, что как общий F для всего фильтра целиком,
так и общий U приводят к отсутствию строк в результате выполнения запроса.
Иными словами, работа U и F, в плане вычисления результата запроса, неразличимы.

Последнее замечание по этой теме такое - кроме All -> Not Exists/ Any -> Exists
может использоваться трансформация в anti join/semi join
В таком случае да, формально говоря, представление о "досрочном выходе из цикла" теряет
смысл (как и первоначальном положении чего либо T), и становится и формально и
технически некорректным, так как алгоритм, который выполняет цикл, формально становится иным,
с иначе формулируемым процессом и результатом вычисления.
----------

далее,
затрагивался вопрос, почему "цикл вычисления для ALL" должен начинаться с true
Общая структура выражения для All, чуть упрощая стиль изъяснения стандарта sql, такая:
выражение-список операция ALL список_сравнения

Если выражение-список на самом деле список, из более чем одного элемента,
то операция может быть только = и !=, иначе может быть любая операция сравнения.
список_сравнения , без потери результата, можно считать множеством_сравнения
Тогда выражение можно читать так - весь предикат принимает значение
для каждого элемента из множества_сравнения (представляющего собой список "того же типа",
что выражение список в левой части) вычисление частичного предиката
выражение-список операция элемент_множества_сравнения
должен давать истину.
Иными словами, такой частичный предикат выполняется на всем множестве сравнения.

Дальше логика строится так, если нечто справедливо по отношению ко всему множеству,
значит оно справедливо и к любому подмножеству этого множества.
И, так как, пустое множество автоматически является подмножеством любого множества,
то и по отношению к пустому множеству тоже.
Это не потому, что так хочется программистам на хаскель, а потому что математика такова
сама по себе, независимо от желаний вообще каких либо программистов.

Деталь же здесь состоит в том, что в отличие от программистов на хаскель,
sql тщательно избегает оперировать в стандарте терминологией теории множеств.
Поэтому он просто кладет на этот вопрос начальное значение true в цикле вычисления
логического значения предиката с мофикатором ALL

Пара слов по поводу "not работает так, как раскрывается"
Касалось оно, главным образом, специфически равенства в качестве операции сравнения,
попробую пояснить.

Сократив до обозначений, запишем выражение для равества с ALL так:
x = ALL (Y), пусть y(i) i-ый элемент непустого Y с n элементами.
Тогда исходное выражение формально раскрывается в
x=y(1) AND x=y(2) ... AND x = н(т)
значения истинности связки p AND q
для двузначной логики можно предстваить так:
ANDTFTTFFFF

а для трехзначной логики так:
ANDTFUTTFUFFFFUUFU

Отрицание этой связки записывается так (трих Шеффера)
NANDTFTFTFTT
для двузначной логики, и так
NANDTFUTFTUFTTTUUTU
для трехзначной.
Т.к. в sql нет самостоятельного обозначения для такой связки, используется эквивалентное
представление в виде
NOT p AND NOT q
автоматически это значит, что
NOT (x = ALL (Y)) преобразуется в x NOT IN (Y),
(пребразующегося в Not Exists) с повтором вышеприведённых рассуждений, основанных на здравом смысле.

Могло бы работать, и приносить пользу в виде используемой ядром системы трансформации такое обстоятельство:
Для множетв значений с хорошо определенными границами
(а для фактических непустых списков это можно считать всегда выполненным)
Выполняются следующие соотношения между ALL/ANY/IN/NOT IN/MIN/MAX:
ANY ALL= IN <> NOT IN< < MAX < MIN<= <=MAX <=MIN> > MIN > MAX>= >=MIN >=MAX
Преобразования ANY/ALL в форму с MIN/MAX не используются из-за того, что в sql MIN/MAX на пустых множествах (списках строк) возвращают Null.
Дейт прямо считает, что это дефект определения этих агрегатных функций в стандарте sql.
Поэтому собственно отрицания неравенств раскрываются аналогично отрицаниям эквивалентнотей,
хотя легко представить себе ситуации, где автоматическое использование преобразований
из MIN в MAX могло бы быть полезным.
Понимая, что делаешь, его можно применять вручную.

Доклад закончил.
Прошу прощения у всех, кто дочитал за отнятое время.
...
Рейтинг: 0 / 0
25.04.2020, 08:23
    #39951264
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему такое поведение запроса
booby,

авторТ.к. в sql нет самостоятельного обозначения для такой связки, используется эквивалентное
представление в виде
NOT p AND NOT q
автоматически это значит, что
NOT (x = ALL (Y)) преобразуется в x NOT IN (Y),
(пребразующегося в Not Exists) с повтором вышеприведённых рассуждений, основанных на здравом смысле.
здесь кони и люди помешались под утро. Виноват.

авторТ.к. в sql нет самостоятельного обозначения для такой связки, используется эквивалентное
представление в виде
NOT (p AND q) => (NOT p OR NOT q),
автоматически это значит, что
NOT (x = ALL (Y)) преобразуется в ( x <> ANY (Y)), что подразумевает выход из цикла по первому несовпадению.

А (x <> ALL (Y)) преобразуется в (эквивалентен) ( x NOT IN (Y), ) (и далее по тексту)
(преобразующегося в Not Exists) с повтором вышеприведённых рассуждений, основанных на здравом смысле.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Почему такое поведение запроса / 21 сообщений из 21, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]