powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Точки перелома сотрудника
6 сообщений из 6, страница 1 из 1
Точки перелома сотрудника
    #39416113
Игорь86
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем доброго времени суток!

Столкнулся с задачей выгрузки истории точек перелома работающего сотрудника (в реальной БД сотрудников очень много и очень много информации по повторным приемам, изменению должностей и переходам по магазинам).
И никак не могу понять, как мне убрать лишние строки.

Используется 4 таблицы
табл1 = za00 - идентификация
IDTN
табл2 = zaes - информация по приему
IDDATENTDATSOR, где DATENT - дата приема, DATSOR - дата увольнения. Если DATSOR = 31.12.2999 - это признак что сотрудник не уволен

табл3 = zaem - информация по должности и отделу
IDDATXXXDATEFFPROFESOTDEL, где DATEFF - дата должности, PROFES и OTDEL - соответственно должность и отдел, DATXXX - это типа системной даты (при первой записи, например должность с 1 января 2011, DATEFF=01.01.2011 а DATXXX=31.12.2999. При добавлении записи, например с 01.06.2011, смотри пример)
пример:
IDDATXXXDATEFFPROFESOTDEL131.12.299901.01.2011KKKPPP
Добавляем запись
IDDATXXXDATEFFPROFESOTDEL101.06.201101.01.2011KKKPPP131.12.299901.06.2011LLLPPP
табл4 = zaga - информация по магазину
IDDATXXXDATEFFCENAFFREGION, где DATEFF - дата начала работы в магазине, CENAFF и REGION - соответственно магазин и регион. Принцип DATXXX тот же.

Есть сотрудник:
za00
IDTN19999999
zaes
IDDATENTDATSOR118.06.200831.08.2008113.07.201031.12.2999
zaem
IDDATXXXDATEFFPROFESOTDEL113.07.201018.06.2008A51101.11.201113.07.2010A51A3101.09.201301.11.2011A51T7131.12.299901.09.2013E77T7
zaga
IDDATXXXDATEFFCENAFFREGION113.07.201018.06.200877701101.11.201113.07.201022201101.11.201201.11.201199999131.12.299901.11.201288888
Что должно получиться в идеале:
ТНДПДУДатаДолжнДолжнОтделДатаМагМаг999999918.06.200831.08.200818.06.2008A5118.06.2008777999999913.07.201031.12.299913.07.2010A51A313.07.2010222999999913.07.201031.12.299901.11.2011A51T701.11.2011999999999913.07.201031.12.299901.11.2011A51T701.11.2012888999999913.07.201031.12.299901.09.2013E77T701.11.2012888
Есть запрос:
Код: 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.
select
t.tn,
a.datent,
a.datsor,
b.dateff,
b.profes,
b.otdel,
c.dateff,
c.cenaff
from
za00 t,
zaes a,
zaem b,
zaga c
where
t.id=a.id
and t.id=b.id
and t.id=c.id
and t.tn in ('9999999')
and b.dateff in
(select z.dateff from za00 x, zaem z where x.id=z.id and x.id=t.id
and z.dateff<=to_date(to_char(a.datsor,'dd.mm.yyyy'),'dd.mm.yyyy') and z.datxxx>to_date(to_char(a.datent,'dd.mm.yyyy'),'dd.mm.yyyy'))
and c.dateff in
(select z.dateff from za00 x, zaga z where x.id=z.id and x.id=t.id
and z.dateff<=to_date(to_char(a.datsor,'dd.mm.yyyy'),'dd.mm.yyyy') and z.datxxx>to_date(to_char(a.datent,'dd.mm.yyyy'),'dd.mm.yyyy'))
order by 1,2,4,7


Но он дублит записи
ТНДПДУДатаДолжнДолжнОтделДатаМагМаг999999918.06.200831.08.200818.06.2008A5118.06.2008777999999913.07.201031.12.299913.07.2010A51A313.07.2010222999999913.07.201031.12.299913.07.2010A51A301.11.2011999999999913.07.201031.12.299913.07.2010A51A301.11.2012888999999913.07.201031.12.299901.11.2011A51T713.07.2010222999999913.07.201031.12.299901.11.2011A51T701.11.2011999999999913.07.201031.12.299901.11.2011A51T701.11.2012888999999913.07.201031.12.299901.09.2013E77T713.07.2010222999999913.07.201031.12.299901.09.2013E77T701.11.2011999999999913.07.201031.12.299901.09.2013E77T701.11.2012888

Как убрать эти дубли? Помогите!!!
...
Рейтинг: 0 / 0
Точки перелома сотрудника
    #39416128
Игорь86,

group by + [min | max] keep(dense_rank [last | first] order by ...)
...
Рейтинг: 0 / 0
Точки перелома сотрудника
    #39416134
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь86,

если кого-то интересует мое мнение (хотя, вряд-ли), naming convention - полное дерьмо.

и еще: попробуй ANSI синтаксис - глядишь, запросы будут понятнее собеседникам
...
Рейтинг: 0 / 0
Точки перелома сотрудника
    #39416287
Игорь86
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый Э - ЭхИгорь86,

group by + [min | max] keep(dense_rank [last | first] order by ...)

И как это можно организовать?
...
Рейтинг: 0 / 0
Точки перелома сотрудника
    #39423963
Игорь86
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добавил к запросу во WHERE это
Код: plsql
1.
2.
and c.dateff<=to_date(to_char(b.datxxx,'dd.mm.yyyy'),'dd.mm.yyyy') and c.datxxx>to_date(to_char(b.dateff,'dd.mm.yyyy'),'dd.mm.yyyy')
and b.dateff<=to_date(to_char(c.datxxx,'dd.mm.yyyy'),'dd.mm.yyyy') and b.datxxx>to_date(to_char(c.dateff,'dd.mm.yyyy'),'dd.mm.yyyy')



И вроде как заработало.
Проверил на 7 сотрудниках - показывает всё как нужно.

Буду тестить дальше.
...
Рейтинг: 0 / 0
Точки перелома сотрудника
    #39424050
Руслан Дамирович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь86,

Код: 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.
WITH
za00 ( ID, TN ) AS (
  SELECT 1, 9999999 FROM dual 
),
zaes ( ID, DATENT, DATSOR ) AS (
  SELECT 1, DATE'2008-06-18', DATE'2008-08-31' FROM dual
  UNION ALL
  SELECT 1, DATE'2010-07-13', DATE'2999-12-31' FROM dual
), 
zaem ( ID, DATXXX, DATEFF, PROFES, OTDEL ) AS (
  SELECT 1, DATE'2010-07-13', DATE'2008-06-18', 'A51', '' FROM dual  
  UNION ALL
  SELECT 1, DATE'2011-11-01', DATE'2010-07-13', 'A51', 'A3' FROM dual
  UNION ALL
  SELECT 1, DATE'2013-09-01', DATE'2011-11-01', 'A51', 'T7' FROM dual
  UNION ALL
  SELECT 1, DATE'2999-12-31', DATE'2013-09-01', 'E77', 'T7' FROM dual
),
zaga ( ID, DATXXX, DATEFF, CENAFF, REGION ) AS (
  SELECT 1, DATE'2010-07-13', DATE'2008-06-18', 777, '01' FROM dual
  UNION ALL
  SELECT 1, DATE'2011-11-01', DATE'2010-07-13', 222, '01' FROM dual
  UNION ALL
  SELECT 1, DATE'2012-11-01', DATE'2011-11-01', 999, '99' FROM dual
  UNION ALL
  SELECT 1, DATE'2999-12-31', DATE'2012-11-01', 888, '88' FROM dual
)
SELECT
  za00.TN,
  zaes.DATENT,
  zaes.DATSOR,
  zaem.DATEFF,
  zaem.PROFES,
  zaem.OTDEL,
  zaga.DATEFF,
  zaga.CENAFF,
  1
FROM
  za00
  LEFT JOIN zaes ON (
        zaes.ID = za00.ID )
  LEFT JOIN zaem ON (
        zaem.ID = zaes.ID
    AND zaem.DATEFF >= zaes.DATENT AND zaem.DATEFF < zaes.DATSOR )
  LEFT JOIN zaga ON (
        zaga.ID = zaes.ID
    AND zaga.DATEFF >= zaes.DATENT AND zaga.DATEFF < zaes.DATSOR )
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Точки перелома сотрудника
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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