powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / условное "отключение" left join
9 сообщений из 9, страница 1 из 1
условное "отключение" left join
    #39889785
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот, допусти, есть left join:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
with
x as (
select level a,
          mod(level,2) b
     from dual
     connect by level < 9
),
y as (
select level a
     from dual
     connect by level < 9
)
select x.a, x.b, y.a
     from x
          left join y
                on x.b != 0
                     and y.a = x.a

Вообще-то, когда я пишу условие x.b != 0 and y.a = x.a, тем самым я кагбы хочу сказать, что в случае когда x.b=0, я бы вообще не хотел чтобы происходил какой-либо доступ к Y.
Но, судя по плану, у оптимизатора другие мысли на этот счет:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
----------------------------------------------------------------------------------------
| Id  | Operation                      | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |      |      1 |    39 |     4   (0)| 00:00:01 |
|*  1 |  HASH JOIN OUTER               |      |      1 |    39 |     4   (0)| 00:00:01 |
|   2 |   VIEW                         |      |      1 |    26 |     2   (0)| 00:00:01 |
|*  3 |    CONNECT BY WITHOUT FILTERING|      |        |       |            |          |
|   4 |     FAST DUAL                  |      |      1 |       |     2   (0)| 00:00:01 |
|   5 |   VIEW                         |      |      1 |    13 |     2   (0)| 00:00:01 |
|*  6 |    CONNECT BY WITHOUT FILTERING|      |        |       |            |          |
|   7 |     FAST DUAL                  |      |      1 |       |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("Y"."A"(+)="X"."A")
       filter("X"."B"<>CASE  WHEN ("Y"."A"(+) IS NOT NULL) THEN 0 ELSE 0 END )
   3 - filter(LEVEL<9)
   6 - filter(LEVEL<9)

Как добиться того, чтобы доступ к "приджоенным" таблицам не осуществлялся вовсе в зависимости от условия, на основе данных из таблиц, уже "просмотренных" (ну, если допустим LEFT JOIN-ов несколько) ?
...
Рейтинг: 0 / 0
условное "отключение" left join
    #39889817
j2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--, т.е. что-то вроде этого:
Код: plsql
1.
left join y  on case when x.b = 0 then null else y.a end = x.a 


?
...
Рейтинг: 0 / 0
условное "отключение" left join
    #39889819
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
explain plan for
with
x as (
select level a,
          mod(level,2) b
     from dual
     connect by level < 9
),
y as (
select level a
     from dual
     connect by level < 9
)
select x.a, x.b, y.a
     from x
          left join y
                on 1 = case
                         when x.b != 0 then 1
                         when  y.a = x.a then 1
                       end
/
SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------
Plan hash value: 3580413835

---------------------------------------------------------------------------------------
| Id  | Operation                      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |      |     1 |    39 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS OUTER            |      |     1 |    39 |     4   (0)| 00:00:01 |
|   2 |   VIEW                         |      |     1 |    26 |     2   (0)| 00:00:01 |
|*  3 |    CONNECT BY WITHOUT FILTERING|      |       |       |            |          |
|   4 |     FAST DUAL                  |      |     1 |       |     2   (0)| 00:00:01 |
|*  5 |   VIEW                         |      |     1 |    13 |     2   (0)| 00:00:01 |
|*  6 |    CONNECT BY WITHOUT FILTERING|      |       |       |            |          |
|   7 |     FAST DUAL                  |      |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(LEVEL<9)
   5 - filter(CASE  WHEN "X"."B"<>0 THEN 1 WHEN "Y"."A"(+)="X"."A" THEN 1 END
              =1)
   6 - filter(LEVEL<9)

22 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
условное "отключение" left join
    #39889823
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--,

не совсем понял что надо
но мож вместо on x.b != 0 достаточно where x.b != 0

......
stax
...
Рейтинг: 0 / 0
условное "отключение" left join
    #39889830
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

36 rows selected.

так задумано?

.....
stax
...
Рейтинг: 0 / 0
условное "отключение" left join
    #39889849
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
Код: plsql
1.
2.
3.
4.
                on 1 = case
                         when x.b != 0 then 1
                         when  y.a = x.a then 1
                       end

в данном (простейшем) случае, может быть, но если таблицы X и Y не маленькие, а колонка Y.a индексирована и хотелось бы иметь возможность задействовать этот индекс? ведь в случае с предикатом 1 = CASE так не получится
...
Рейтинг: 0 / 0
условное "отключение" left join
    #39889852
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax

так задумано?


Упс:

Код: 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.
explain plan for
with
x as (
select level a,
          mod(level,2) b
     from dual
     connect by level < 9
),
y as (
select level a
     from dual
     connect by level < 9
)
select x.a, x.b, y.a
     from x
          left join y
                on 1 = case
                         when x.b != 0 then case
                                              when  y.a = x.a then 1
                                            end
                       end
/
SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 3580413835

---------------------------------------------------------------------------------------
| Id  | Operation                      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |      |     1 |    39 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS OUTER            |      |     1 |    39 |     4   (0)| 00:00:01 |
|   2 |   VIEW                         |      |     1 |    26 |     2   (0)| 00:00:01 |
|*  3 |    CONNECT BY WITHOUT FILTERING|      |       |       |            |          |
|   4 |     FAST DUAL                  |      |     1 |       |     2   (0)| 00:00:01 |
|*  5 |   VIEW                         |      |     1 |    13 |     2   (0)| 00:00:01 |
|*  6 |    CONNECT BY WITHOUT FILTERING|      |       |       |            |          |
|   7 |     FAST DUAL                  |      |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(LEVEL<9)
   5 - filter(CASE  WHEN "X"."B"<>0 THEN CASE "Y"."A"(+) WHEN "X"."A" THEN 1
              END  END =1)
   6 - filter(LEVEL<9)

22 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
условное "отключение" left join
    #39889865
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax
мож вместо on x.b != 0 достаточно where x.b != 0
не достаточно, поскольку в общем случае это нужно для следующего:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select *
	from t0
		left join t1
			on t1.id = t0.id
		left join t2
			on t1.a = 'INCLUDE-T2'
				and t2.id = t0.id
		left join t3
			on t1.a = 'INCLUDE-T2'
				and t2.a = 'INCLUDE-T3'
				and t3.id = t0.id
...
Рейтинг: 0 / 0
условное "отключение" left join
    #39889930
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Да просто вместо хэш джойна форсируйте нестед лупс...
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / условное "отключение" left join
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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