powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Эффективен ли запрос если в условии джойна есть >=?
25 сообщений из 29, страница 1 из 2
Эффективен ли запрос если в условии джойна есть >=?
    #32138245
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица затрат рабочего времени

WORK (EMPLOYEE_ID, WORK_DATE, WORK_DURATION)

есть таблица динамики почасовой ставки

HOUR_RATE (EMPLOYEE_ID, CHANGE_DATE, RATE_VALUE)

для каждого EMPLOYEE MIN(CHANGE_DATE) = MIN(WORK_DATE). Так что случай, что для некоторой WORK_DATE не определена RATE_VALUE, исключен.

Необходимо вычислить, сколько каждый сотрудник заработал. Для этого составила запрос (допустим индексы по EMPLOYEE_ID и DATE полям для обеих таблиц есть)

Код: plaintext
1.
2.
3.
4.
5.
SELECT 
WORK.EMPLOYEE_ID, 
SUM(WORK.WORK_DURATION * HOUR_RATE.RATE_VALUE) AS COSTS 
FROM WORK 
INNER JOIN HOUR_RATE ON (WORK.EMPLOYEE_ID = HOUR_RATE.EMPLOYEE_ID AND 
                         WORK.WORK_DATE >= HOUR_RATE.CHANGE_DATE)


Гложет сомнение, что такое использование джойна с условием >=, не есть лучшее решение. Есть ли лучшие варианты?

И еще теоретический вопрос. Допустим нужно запросить эти данные только для одного сотрудника. Как лучше сделать - добавить WHERE WORK.EMPLOYEE_ID = 5 или добавить в джойн AND WORK.EMPLOYEE_ID = 5? Вобще наш спец по DB2 говорит, что при создании запроса стоит заботиться только о его читабельности и наглядности, любая нормальная база все равно его соптимизит по своему усмотрению. Так ли это?
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138259
Фотография Scott Tiger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Афигенный у вас админ. Я, конечно, понимаю - "красивый самолёт и летать будет красиво", но всё же это не авиация...
2. Посмотри план и статистику. В плюсе - set autot exp stat, при этом у тебя должна быть роль plustrace (если роли нет, создать через $ORACLE_HOME/sqlplus/admin/plustrce.sql)
3. Не пиши запросы с конструкциями типа inner join someshit on someothershit - мало того, что такие конструкции крайне неудобно читать и понимать, оно ещё и не работает в oracle 8i и ниже. Есть гораздо более понятный и удобный синтаксис.
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138260
Фотография Scott Tiger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пардон - set autot trace exp stat
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138291
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вообще-то есть сомнение в правильности запроса...
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138305
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Scott Tiger

А что за синтаксис ты имеешь ввиду? В кратце мой вопрос, стоит ли избегать использовать >= в джойнах? Или на него нельзя ответить однозначно?

По поводу не работает в oracle 8i : я начала с 9i, не могла знать.

to ksukhonosenko

Да действительно, я GROUP BY забыла. Извиняюсь.
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138334
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Scott Tiger

Ты имеешь ввиду?

Код: plaintext
1.
2.
3.
4.
SELECT * FROM tab1 LEFT JOIN tab2 ON col1=col2  - аналогичен запросу:
SELECT * FROM tab,tab2  WHERE col1=col2 (+)

SELECT * FROM tab1 RIGHT JOIN tab2 ON col1=col2  - аналогичен запросу:
SELECT * FROM tab,tab2  WHERE col1 (+)=col2 
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138345
Фотография Scott Tiger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насчёт избегания >= - сложно сказать. Обычно такие конструкции приводят к полному сканированию таблицы. Но надо смотреть план.
Что касается синтаксиса - совершенно верно. Разве что следует добавить, что inner join аналогичен SELECT * FROM tab,tab2 WHERE col1=col2.
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138353
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Во-первых GROUP BY сотрудник, а во-вторых кажется что один и тот же duration используется при расчете по разным ставкам - не видно как duration раскладывается на "разнооплатные" составляющие. Может, правда я неверно проинтерпретировал значение атрибутов или у вас есть еще дополнительные правила, которые из запроса не следуют... Ручной расчет-то подтверждает результаты?
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138440
AI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Операция >= как правило приводит к индексному скану (если столбец индексирован).
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138514
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Scott Tiger

A если несколько джойнов то AND использовать?

SELECT * FROM tab,tab2,tab3 WHERE col1=col2 and col3=col4

Выглядит несколько необычно. И что, действительно более удобочитаемо?

to ksukhonosenko

Насчет двойного использования ты был прав, надо еще добавить

AND HOUR_RATE.CHANGE_DATE = (SELECT MAX(CHANGE_DATE) FROM HOUR_RATE WHERE CHANGE_DATE <= WORK.WORK_DATE)

вот конечный запрос (с учетом пожелания Scott Tiger)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT 
WORK.EMPLOYEE_ID, 
SUM(WORK.WORK_DURATION * HOUR_RATE.RATE_VALUE) AS COSTS
 
FROM WORK, HOUR_RATE 

WHERE 
WORK.EMPLOYEE_ID = HOUR_RATE.EMPLOYEE_ID AND
WORK.WORK_DATE >= HOUR_RATE.CHANGE_DATE AND

HOUR_RATE.CHANGE_DATE = (SELECT MAX(CHANGE_DATE) FROM HOUR_RATE WHERE CHANGE_DATE <= WORK.WORK_DATE)

GROUP BY WORK.EMPLOYEE_ID
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138574
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Теперь получается, что для каждой даты из табл. WORK ставится в соответствие одна запись из таблицы RATE (с макимальной датой, не превышающей дату в WORK) - это разве верно?
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138601
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да как раз, то что нужно. HOUR_RATE это история изменений ЗП.

Например

01.04.2003 40$
06.01.2003 50$
09.01.2003 55$

Соответсвенно на все даты периода

01.04.2003 - 05.01.2003 действует ставка 40$
06.01.2003 - 09.01.2003 - 50$
09.01.2003 - - 55$ пока не добавится новая ставка
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138617
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С датами я нагородила, исправленный вариант

Да как раз, то что нужно. HOUR_RATE это история изменений ЗП.

Например

01.04.2003 40$
01.06.2003 50$
01.09.2003 55$

Соответсвенно на все даты периода

01.04.2003 - 31.05.2003 действует ставка 40$
01.06.2003 - 31.08.2003 - 50$
01.09.2003 - 55$
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138618
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А что такое duration? Пересекать границы изменения ставки может?
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138627
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WORK_DURATION количество отработанного времени в часах на дату WORK_DATE.
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138637
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так пересекать границу изменения ставки может?
Вы считаете по последней ставке, но по полной длительности. Если длительность больше последнего диапазона изменения ставки (то есть надо считать по нескольким ставкам), то вы считаете неверно имхо. Если же нужно считать по последней ставке, то запрос можно написать проще - взять последнюю ставку и умножить на длительность и суммировать нечего. Зачем тогда sum в селекте, если нужна только одна строка?

Лучше б сначала на бумаге решение написать...
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138647
Angel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рекомендую всегда для таких таблиц заводить не поле ДАТА (кстати, не понимаю, неужели именовать объекты и атрибуты по-русски менее удобно, чем по ... не знаю даже по-какому :-) ), а поля ДАТА_КОН и ДАТА_НАЧ. ДАТА_КОН помещать в первичный ключ и поддерживать ёлку:
например,
НОМЕР | ДАТА_КОН | ДАТА_НАЧ | ЗНАЧЕНИЕ ...

1 05.01.2003 01.01.1980 100 ...
1 10.02.2003 05.01.2003 200 ...
1 01.01.3000 10.02.2003 500 ...
...

В ключе НОМЕР И ДАТА_КОН. Плюс индекс на НОМЕР, ДАТА_КОН, ДАТА_НАЧ.
В запросе использовать: :дНашаДата BETWEEN ДАТА_НАЧ AND ДАТА_КОН - 1 (либо BETWEEN ДАТА_НАЧ + 1 AND ДАТА_КОН, это уж как удобнее).

Значительно жизнь упрощает. Никаких <= не надо.
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138661
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Angel

для программера твой вариант конечно более удобен, а юзер просто хочет вводить дату начала действия новой ставки и ее значение. Конечно можно такой юзерский интерфейс поддерживать и с наличием ДАТА_НАЧ AND
ДАТА_КОН, при добавлении новой ставки вычисляя ДАТА_КОН = [ДАТА_НАЧ новой ставки] - 1 день.
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138664
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Именно так и надо. Не надо путать данные и их представление. Если пользователь хочет это видеть, не значит вовсе что так лучше и хранить.
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138669
Angel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>для программера твой вариант конечно более удобен, а юзер просто хочет вводить дату начала действия новой ставки и ее значение

:-) Наверное, все же наоборот. Время отклика уменьшится. А как вводил он дату, так и будет вводить. Дело программиста, как ты и говоришь, строить елку (собственно триггер повесить и все).
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138679
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А почему "елка"? В смысле откуда такое название?

Виолина, вы уверены в правильности расчета? Так как ставки у вас растут - в случае неверного расчета, по вашей вине будет перерасход - это значит "без премии" :)
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138686
Angel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нарисовать, к сожалению, не могу.
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138822
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Раз есть желающие поразбираться (ksukhonosenko), давайте. Возьмем одного сотрудника и пару отчетов за даты с разными ставками.

Допустим сотрудник 1 работал таким образом

таблица WORK
Код: plaintext
1.
2.
3.
4.
5.
6.
    ID     EMPLOYEE_ID      WORK_DATE      WORK_DURATION 
 ---------- ---------- -------------------- ---------- 
 
          1            1            11 - 04 - 2003            8  
          2            1            12 - 04 - 2003            8  
          3            1             3 - 05 - 2003            6  
          4            1             4 - 05 - 2003            9  


Его почасовая ставка с 1 апреля 40 а с 1 мая 60 баков (быстро он поднялся!).

таблица HOUR_RATE
Код: plaintext
1.
2.
3.
4.
    ID     EMPLOYEE_ID     CHANGE_DATE     RATE_VALUE 
 ---------- ---------- -------------------- ---------- 
 
          1            1             1 - 04 - 2003           40  
          2            1             1 - 05 - 2003           60  


Чуть чуть модифицируем исходный запрос, чтобы увидеть что же все таки суммируется

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT 
WORK.EMPLOYEE_ID, 
WORK.WORK_DATE,
WORK.WORK_DURATION,
HOUR_RATE.RATE_VALUE,
(WORK.WORK_DURATION*HOUR_RATE.RATE_VALUE) AS COSTS
 
FROM WORK, HOUR_RATE 

WHERE 
WORK.EMPLOYEE_ID = HOUR_RATE.EMPLOYEE_ID AND
WORK.WORK_DATE >= HOUR_RATE.CHANGE_DATE AND

HOUR_RATE.CHANGE_DATE = (SELECT MAX(CHANGE_DATE) FROM HOUR_RATE WHERE CHANGE_DATE <= WORK.WORK_DATE)

ORDER BY WORK.WORK_DATE


получаем (спул все таки класная штука!)

Код: plaintext
1.
2.
3.
4.
5.
6.
EMPLOYEE_ID      WORK_DATE      WORK_DURAT RATE_VALUE    COSTS   
 ---------- -------------------- ---------- ---------- ---------- 
 
          1            11 - 04 - 2003            8           40          320  
          1            12 - 04 - 2003            8           40          320  
          1             3 - 05 - 2003            6           60          360  
          1             4 - 05 - 2003            9           60          540  



возвращаясь к сумме имеем

Код: plaintext
1.
2.
3.
EMPLOYEE_ID   COSTS   
 ---------- ---------- 
 
          1         1540 


Все ОК!
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138842
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так я ж сразу спросил, duration может пересекать изменение ставки или нет. Я трактовал duration как длительность работы в днях. И кажется не только я - об этом свидетельствует разговор о "елках".

А что касается "раз есть желающие поразбираться", то ваш изначальный запрос был неверен :) - где мое "спасибо", короче?.
...
Рейтинг: 0 / 0
Эффективен ли запрос если в условии джойна есть >=?
    #32138860
Violina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо!

Особенно за важные примечания. Чтобы вообще все было ОК, надо добавить валидацию WORK_DURATION - не более 24 часов в день.
...
Рейтинг: 0 / 0
25 сообщений из 29, страница 1 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Эффективен ли запрос если в условии джойна есть >=?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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