LINUX.ORG.RU

есть ли проще вариант запроса

 , ,


1

1

Исходное: В СУБД (oracle 11g on RH) имеются следующие таблицы:

таблица "T"
  ID_T NUMBER PRIMARY KEY;
  NAME_T NCLOB [NULL NOT ALLOW];
Таблица "RRR"
  ID_RRR NUMBER PRIMARY KEY;
  ID_T_A NUMBER [NULL ALLOW]; отношение many-to-one к T.ID_T
  ID_T_B NUMBER [NULL ALLOW]; отношение many-to-one к T.ID_T
  ID_T_C NUMBER [NULL ALLOW]; отношение many-to-one к T.ID_T
  ID_T_D NUMBER [NULL ALLOW]; отношение many-to-one к T.ID_T
  ID_T_E NUMBER [NULL ALLOW]; отношение many-to-one к T.ID_T
  DT TIMESTAMP [NULL NOT ALLOW];
Хочу получить таблицу(или view) аналогичную «RRR», но вместо идентификаторов ID_T_* их соответствующее значение из таблицы «T», т.е.
Таблица(view) "RRR_T"
  ID_RRR NUMBER PRIMARY KEY;
  NAME_T_A NCLOB;
  NAME_T_B NCLOB;
  NAME_T_C NCLOB;
  NAME_T_D NCLOB;
  NAME_T_E NCLOB;
  DT TIMESTAMP ;
Но кроме как пяти вложенных join на ум ничего не идет. Нагружать сервер этим не очень хочется. Может есть какие то другие способы о которых незнаю?

★★★★★

Последнее исправление: Atlant (всего исправлений: 1)

получить пары ID_T->NAME_T отдельным запросом и на стороне приложения подставить?

только это уже будет три запроса:
получить множество id_t из RRR
получить соответствующие пары из T
получить записи из RRR

надо запустить какой-нить профилировщик запросов и сравнить. :)

а на стороне СУБД - да, джойнить таблицы.

aol ★★★★★
()
Последнее исправление: aol (всего исправлений: 1)
Ответ на: комментарий от aol

ну да ещё конечно на стороне клиента сопоставлять, но хотелось бы обойтись сервером. и не ресурсоёмким образом.

Atlant ★★★★★
() автор топика
WITH 
"T" AS (
  SELECT 1 AS "ID", 'Да' AS "NAME" FROM dual
  UNION ALL
  SELECT 2 AS "ID", 'Нет' AS "NAME" FROM dual
), 
"RRR" AS (
  SELECT 1 AS "ID", 1 AS "A1", 2 AS "B1" FROM dual
  UNION ALL
  SELECT 2 AS "ID", 2 AS "A1", 1 AS "B1" FROM dual
) 
SELECT /* MATERIALIZE */
       R.ID, T1.NAME, T2.NAME
FROM RRR R, T T1, T T2 
WHERE R.A1 = T1.ID
  AND R.B1 = T2.ID
ThePretender
()
Ответ на: комментарий от ThePretender

да, так тоже можно. Вот только, что через join, что простым where, судя по плану, запроса выполняются одинаково

Для вложеного join

"---------------------------------------------------------"
"| Id  | Operation                        | Name         |"
"---------------------------------------------------------"
"|   0 | SELECT STATEMENT                 |              |"
"|   1 |  NESTED LOOPS OUTER              |              |"
"|   2 |   NESTED LOOPS OUTER             |              |"
"|   3 |    NESTED LOOPS OUTER            |              |"
"|   4 |     NESTED LOOPS OUTER           |              |"
"|   5 |      NESTED LOOPS OUTER          |              |"
"|   6 |       TABLE ACCESS FULL          | RRR          |"
"|   7 |       TABLE ACCESS BY INDEX ROWID| T            |"
"|   8 |        INDEX UNIQUE SCAN         | T_PK         |"
"|   9 |      TABLE ACCESS BY INDEX ROWID | T            |"
"|  10 |       INDEX UNIQUE SCAN          | T_PK         |"
"|  11 |     TABLE ACCESS BY INDEX ROWID  | T            |"
"|  12 |      INDEX UNIQUE SCAN           | T_PK         |"
"|  13 |    TABLE ACCESS BY INDEX ROWID   | T            |"
"|  14 |     INDEX UNIQUE SCAN            | T_PK         |"
"|  15 |   TABLE ACCESS BY INDEX ROWID    | T            |"
"|  16 |    INDEX UNIQUE SCAN             | T_PK         |"
"---------------------------------------------------------"
для простого where
"---------------------------------------------------------"
"| Id  | Operation                        | Name         |"
"---------------------------------------------------------"
"|   0 | SELECT STATEMENT                 |              |"
"|   1 |  NESTED LOOPS                    |              |"
"|   2 |   NESTED LOOPS                   |              |"
"|   3 |    NESTED LOOPS                  |              |"
"|   4 |     NESTED LOOPS                 |              |"
"|   5 |      NESTED LOOPS                |              |"
"|   6 |       TABLE ACCESS FULL          | RRR          |"
"|   7 |       TABLE ACCESS BY INDEX ROWID| T            |"
"|   8 |        INDEX UNIQUE SCAN         | T_PK         |"
"|   9 |      TABLE ACCESS BY INDEX ROWID | T            |"
"|  10 |       INDEX UNIQUE SCAN          | T_PK         |"
"|  11 |     TABLE ACCESS BY INDEX ROWID  | T            |"
"|  12 |      INDEX UNIQUE SCAN           | T_PK         |"
"|  13 |    TABLE ACCESS BY INDEX ROWID   | T            |"
"|  14 |     INDEX UNIQUE SCAN            | T_PK         |"
"|  15 |   TABLE ACCESS BY INDEX ROWID    | T            |"
"|  16 |    INDEX UNIQUE SCAN             | T_PK         |"
"---------------------------------------------------------"

Atlant ★★★★★
() автор топика

попробуем поизвращаться

select id_rrr, 
case when id_t_a = id_t then name_t else null end name_t_a,
case when id_t_b = id_t then name_t else null end name_t_b,
case when id_t_c = id_t then name_t else null end name_t_c,
case when id_t_d = id_t then name_t else null end name_t_d,
case when id_t_e = id_t then name_t else null end name_t_e
from rrr, t 
where id_t_a = id_t 
   or id_t_b = id_t 
   or id_t_c = id_t 
   or id_t_d = id_t 
   or id_t_e = id_t
select id_rrr, 
case when id_t_a = id_t then name_t else null end name_t_a,
case when id_t_b = id_t then name_t else null end name_t_b,
case when id_t_c = id_t then name_t else null end name_t_c,
case when id_t_d = id_t then name_t else null end name_t_d,
case when id_t_e = id_t then name_t else null end name_t_e
from rrr, t where id_t in (id_t_a,id_t_b,id_t_c,id_t_d,id_t_e)
aydar ★★★★★
()
Ответ на: попробуем поизвращаться от aydar

да как ни крути все одно будет... Есть кстати базы, которые такие словари умеют прятать от пользователя. Т.е. в таблице вставляются и селектятся прямо значения, а таблица словарь создается и поддерживается невидимо для пользоветеля.

vromanov ★★★
()
Ответ на: комментарий от Atlant

Попробуйте хинт /*+ MATERIALIZE */ в подзапрос T поставить. Это конечно при условии, что данных в таблице немного.

ThePretender
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.