powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Предикат по короткому условию
13 сообщений из 13, страница 1 из 1
Предикат по короткому условию
    #40134651
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго дня господа !

Имею запрос

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                   ) 



Можно ли дать указание запросу работать по короткому условию констант (T1.F1=1) если это условие истинно,
не обращаться к таблице T2
И как это проверить

Спасибо !

Мысль такая
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                       and T1.F1<>1
                       and T1.F2<>2
                   ) 
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40134656
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X

Можно ли дать указание запросу работать по короткому условию констант (T1.F1=1) если это условие истинно,
не обращаться к таблице T2
И как это проверить


CASE:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SELECT  * 
  FROM  T1
  WHERE 1 = CASE
              WHEN T1.F1 = 1 THEN 1
              WHEN T1.F2 = 2 THEN 1
              ELSE (
                    SELECT  1
                      FROM T2
                      WHERE T2.F1 = T1.F3
                        AND ROWNUM = 1 
                    )
            END
/




как это проверить:

Код: 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.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
SQL> CREATE TABLE T1
  2    AS
  3      SELECT  1 F1,
  4              1 F2,
  5              1 F3
  6        FROM  DUAL
  7  /

Table created.

SQL> CREATE TABLE T2(F1 NUMBER)
  2  /

Table created.

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1 / 0
  6                ELSE (
  7                      SELECT  1 / 0
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /

        F1         F2         F3
---------- ---------- ----------
         1          1          1

SQL> INSERT INTO T1 VALUES(2,2,2)
  2  /

1 row created.

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1 / 0
  6                ELSE (
  7                      SELECT  1 / 0
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /
ERROR:
ORA-01476: divisor is equal to zero



no rows selected

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1
  6                ELSE (
  7                      SELECT  1 / 0
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /

        F1         F2         F3
---------- ---------- ----------
         1          1          1
         2          2          2

SQL> INSERT INTO T1 VALUES(3,3,3);

1 row created.

SQL> INSERT INTO T2 VALUES(3);

1 row created.

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1
  6                ELSE (
  7                      SELECT  1 / 0
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /
ERROR:
ORA-01476: divisor is equal to zero



no rows selected

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1
  6                ELSE (
  7                      SELECT  1
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /

        F1         F2         F3
---------- ---------- ----------
         1          1          1
         2          2          2
         3          3          3

SQL>



SY.
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40134666
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

Понял Вас !

Надеялся увидеть параметры настройки базы на манер Hint-ов
У Delphi есть аналогичное - анализ короткой или полной логики условия

Но так тоже подойдет !
Спасибо
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40134669
ASNexus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
HOME_X
Доброго дня господа !

Имею запрос

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                   ) 


Можно ли дать указание запросу работать по короткому условию констант (T1.F1=1) если это условие истинно,
не обращаться к таблице T2
И как это проверить

Этот запрос будет выполняться именно так, как Вам нужно: в первую очередь производится проверка условий, в которых сравнение с константами, в т.ч. IS [NOT] NULL, потом уже выполнение подзапросов, вызовы функций и т.п. Независимо от порядка этих условий в WHERE.
Где это прочитать в доке - так с ходу не вспомню. Проверить можно примерами на разных исходных данных, вроде тех, что SY ниже написал.
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40134671
ASNexus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, MSSQL в подзапросах [NOT] EXISTS игнорирует всё, что перечислено в его SELECT (может быть это регулируется параметрами - тут не скажу, не знаю), т.е. можно написать что-то вроде "where exists (select 1/0 from ...)" и это не вызовет ошибку "divisor is equal to zero". Возможно Oracle в какой-то версии это тоже сделает (или уже сделал). Исходя из этого, я бы для проверки того, выполняется подзапрос или нет добавил бы условие в WHERE подзапроса, что-то вроде "and T2.F1 / 0 > 0"
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40134680
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASNexus
Кстати, MSSQL в подзапросах [NOT] EXISTS игнорирует всё, что перечислено в его SELECT
(может быть это регулируется параметрами - тут не скажу, не знаю),
т.е. можно написать что-то вроде "where exists (select 1/0 from ...)" и это не вызовет ошибку "divisor is equal to zero".

Возможно Oracle в какой-то версии это тоже сделает (или уже сделал).
Исходя из этого, я бы для проверки того, выполняется подзапрос или нет
добавил бы условие в WHERE подзапроса, что-то вроде "and T2.F1 / 0 > 0"


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> SELECT banner_full FROM v$version;

BANNER_FULL                                                                                                                                                     
-------------------------------------------------------------------------------
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.4.0.0.0

SQL> SELECT D.department_id, D.department_name 
  2  FROM departments D
  3  WHERE NOT EXISTS (SELECT 1/0 FROM employees E 
  4                    WHERE D.department_id = E.department_id)
  5    AND ROWNUM <= 3;

DEPARTMENT_ID DEPARTMENT_NAME               
------------- ------------------------------
          120 Treasury                      
          130 Corporate Tax                 
          140 Control And Credit  


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

Лично я обычно там ставлю * (звездочку).
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40134691
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
ASNexus
Кстати, MSSQL в подзапросах [NOT] EXISTS игнорирует всё, что перечислено в его SELECT
Oracle тоже.
ASNexus
"where exists (select 1/0 from ...)" и это не вызовет ошибку "divisor is equal to zero"
смотрите внимательнее, там где ошибка, там было не exists, а просто скалярный подзапрос.
ASNexus
я бы для проверки того, выполняется подзапрос или нет добавил бы условие в WHERE подзапроса, что-то вроде "and T2.F1 / 0 > 0"
вообще это не очень хороший способ проверять, что выполняется...
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40134969
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sayan Malakshinov,

В качестве проверки использовал поль. функцию , в которую передаю
уникальное значение записи и это значение выводиться в консоль

В целом процесс отслеживается

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                        and MyFunc(T1.F3)=1
                   ) 



ASNexus
Насчет последовательности - Вы правы - первично идут константы.
Ссылка на таблицу в последную очередь

Спасибо
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40135441
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X,

когда вы добавили and MyFunc(T1.F3)=1
то получили совершенно другой запрос
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40135442
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X
Насчет последовательности - Вы правы - первично идут константы.
Ссылка на таблицу в последную очередь
а какие индексы у вас есть?
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40135540
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X

В качестве проверки использовал поль. функцию

если T2.F1=T1.F3 == FALSE, то ф-цию можно и не вызывать

.....
stax
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40135704
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
HOME_X
Sayan Malakshinov,

В качестве проверки использовал поль. функцию , в которую передаю
уникальное значение записи и это значение выводиться в консоль

В целом процесс отслеживается

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                        and MyFunc(T1.F3)=1
                   ) 

введение в запрос функций может заблокировать трансформации. Например, может быть заблокирован join/subquery elimination при FK - тогда без функции подзапрос бы не выполнялся, а из-за добавления функции ораклу придется его выполнять
...
Рейтинг: 0 / 0
Предикат по короткому условию
    #40135752
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sayan Malakshinov

введение в запрос функций может заблокировать трансформации. Например, может быть заблокирован join/subquery elimination при FK - тогда без функции подзапрос бы не выполнялся, а из-за добавления функции ораклу придется его выполнять


преследовал цель - отследить последовательность выполнения кода.
Получил вполне ожидаемый результат - в продуктиве такого не будет
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Предикат по короткому условию
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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