Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Как избежать двойного joina по большой таблице  [new]
skelet
Member [заблокирован]

Откуда: moskau
Сообщений: 5549
Есть вьюшка acc_all и табличка account
Необходимо получить все записи из вьюшки, которые есть в account, но с меньшей датой модификации (modif_dt) для любого номера счёта (acc_number) и только в случае различного acc_title

Работает такое решение

SELECT ta.*
FROM acc_all ta
JOIN
(SELECT ra.acc_number, MAX (ra.modif_dt) md
FROM account ra JOIN acc_thaler_all ta1
ON ra.acc_title <> ta1.acc_title
GROUP BY ra.acc_number) sel
ON ta.acc_number = sel.acc_number AND ta.modif_dt > sel.md

но мне не нравится, что дважды джоинится большая вьюха acc_all. Хотелось бы этого избежать

единственное, что я смог придумать -

select ta.*
from acc_all ta
join account ra on ra.acc_number = ta.acc_number
and ra.acc_title <> ta.acc_title
and ra.acc_number in
(select acc_number from (
select acc_number, max(modif_dt) md
from rs_account
group by acc_number
)
)

Но тут явно некрасиво, что приходится лишним селектом убирать столбец
(select acc_number from (
select acc_number, max(modif_dt) md ...

Как-нибудь можно красиво и по нормальному решить проблему?
1 апр 08, 18:37    [5488981]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
_мухомор
Guest
Чтобы решить задачу, нужно иметь ее внятное описание. А тут второй запрос возвращает совсем не то же, что и первый. И условие задано так, что допускает неоднозначную трактовку.

Покажите на тестовом наборе данных, что должен возвращать запрос.
1 апр 08, 18:55    [5489078]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
skelet
Member [заблокирован]

Откуда: moskau
Сообщений: 5549
Пардон что именно не одно и то же? Все поля not null строго.
1 апр 08, 19:02    [5489115]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
kapelan
Member

Откуда: хутор БольшойБугор
Сообщений: 722
в лоб по тексту:
Необходимо получить все записи из вьюшки, которые есть в account
SELECT * 
FROM из_вьюшки вью
JOIN  account    acc
  ON  ....

 но с меньшей датой модификации (modif_dt) для любого номера счёта (acc_number) и только в случае различного acc_title
WHERE вью.modif_dt < acc.modif_dt 
 AND вью.acc_title < acc.acc_title  
1 апр 08, 19:22    [5489163]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
Robb
Member

Откуда: там и тут
Сообщений: 949
Ник,
Снчала создавать временную таблицу с интересующими параметрами из вложенного селекта и затем делать нормальный первый селект, без "изврата"... )))
1 апр 08, 20:22    [5489295]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
==Tims==
Member [заблокирован]

Откуда: Гена Евтушенко
Сообщений: 343
skelet
Есть вьюшка acc_all и табличка account
дважды джоинится большая вьюха acc_all
[/quote]

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

SELECT ta.*
  FROM acc_all ta
       JOIN
       (SELECT   ra.acc_number, MAX (ra.modif_dt) md
            FROM account ra JOIN acc_thaler_all ta1
                 ON ra.acc_title <> ta1.acc_title
        GROUP BY ra.acc_number) sel
       ON ta.acc_number = sel.acc_number AND ta.modif_dt > sel.md


где два раза-то???


[SRC oracle]
единственное, что я смог придумать -

select ta.*
from acc_all ta
join account ra on ra.acc_number = ta.acc_number
and ra.acc_title <> ta.acc_title
and ra.acc_number in
(select acc_number from (
select acc_number, max(modif_dt) md
from rs_account
group by acc_number
)
)



и как вы получили из первого запроса второй?
1 апр 08, 21:38    [5489399]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
==Tims==
Member [заблокирован]

Откуда: Гена Евтушенко
Сообщений: 343
Robb
Ник,
Снчала создавать временную таблицу с интересующими параметрами из вложенного селекта и затем делать нормальный первый селект, без "изврата"... )))

вообще-то with никто не отменял пока
1 апр 08, 21:39    [5489402]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
skelet
Member [заблокирован]

Откуда: moskau
Сообщений: 5549
==Tims== автор просто не разбирается ещё в деталях, и автору не нравится
SELECT ta.*
FROM acc_all ta
JOIN
(SELECT ra.acc_number, MAX (ra.modif_dt) md
FROM account ra JOIN acc_all ta1 вот этот второй join, ибо в первом селекте выборка из той же вьюхи.
2 апр 08, 10:51    [5490658]     Ответить | Цитировать Сообщить модератору
 давайте переформулируем вопрос  [new]
skelet
Member [заблокирован]

Откуда: moskau
Сообщений: 5549
SELECT ta.*
FROM acc ta
JOIN
(SELECT ra.acc_number, MAX (ra.modif_dt) md
FROM account ra JOIN acc ta1
ON ra.acc_title <> ta1.acc_title
GROUP BY ra.acc_number) sel
ON ta.acc_number = sel.acc_number AND ta.modif_dt > sel.md


можно ли его привести в приличный вид?
2 апр 08, 10:56    [5490692]     Ответить | Цитировать Сообщить модератору
 Re: давайте переформулируем вопрос  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
skelet
можно ли его привести в приличный вид?
Для начала использовать кнопку SRC при оформлении кода.

Если account.acc_number уникально, то можно попробовать так:
select * from (
  SELECT ta1.*, ra.acc_number, MAX(ra.modif_dt) over (partition by ra.acc_number) md
   FROM account ra, acc ta1
   WHERE ra.acc_title <> ta1.acc_title
    AND tal.acc_number = ra.acc_number
)
where modif_dt > md
2 апр 08, 11:38    [5490992]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
skelet
Member [заблокирован]

Откуда: moskau
Сообщений: 5549
хорошо, учту ))

А как насчёт, вот мне в голову пришло

SELECT ta.*, 108 typeoperid
  FROM acc_thaler_all_table ta JOIN rs_account ra
       ON ra.acc_number = ta.acc_number AND ra.acc_title <> ta.acc_title
       JOIN
       (SELECT   acc_number, MAX (modif_dt) md
            FROM rs_account
        GROUP BY acc_number) sel
       ON sel.acc_number = ra.acc_number AND ta.modif_dt > sel.md
       
       

Насколько это хуже вашего кода?
2 апр 08, 11:56    [5491144]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
skelet
А как насчёт, вот мне в голову пришло

SELECT ta.*, 108 typeoperid
  FROM acc_thaler_all_table ta JOIN rs_account ra
       ON ra.acc_number = ta.acc_number AND ra.acc_title <> ta.acc_title
       JOIN
       (SELECT   acc_number, MAX (modif_dt) md
            FROM rs_account
        GROUP BY acc_number) sel
       ON sel.acc_number = ra.acc_number AND ta.modif_dt > sel.md
       
       

Насколько это хуже вашего кода?
Я не могу сравнивать разные запросы :)
но если не придираться, то что мешает сравнить по скорости? :)
2 апр 08, 12:01    [5491197]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
skelet
Member [заблокирован]

Откуда: moskau
Сообщений: 5549
мешает как минимум отсутствие понимания как это грамотно прочекать, неужели просто запустить тест в Тоаде? )

А в вашем коде, не кажется ли вам, что этот
MAX(ra.modif_dt) over (partition by ra.acc_number)
это и есть
SELECT ra.acc_number, MAX (ra.modif_dt) md
GROUP BY ra.acc_number
?

Хотя конечно смотрится неплохо по читабельности )
2 апр 08, 12:17    [5491348]     Ответить | Цитировать Сообщить модератору
 Re: Как избежать двойного joina по большой таблице  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
skelet
мешает как минимум отсутствие понимания как это грамотно прочекать, неужели просто запустить тест в Тоаде? )
ну да, как минимум посмотреть просто по скорости выполнения.

skelet
А в вашем коде, не кажется ли вам, что этот
MAX(ra.modif_dt) over (partition by ra.acc_number)
это и есть
SELECT ra.acc_number, MAX (ra.modif_dt) md
GROUP BY ra.acc_number
?
Было бы странно, если бы это было не оно :)
2 апр 08, 12:19    [5491375]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить