powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Дни отпуска
25 сообщений из 156, страница 1 из 7
Дни отпуска
    #39448750
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день. Имеется длинная динамическая функция, которая проходит по таблице График. В этой таблице есть столбцы год, код сотрудника и 52 столбца, которые подразумевают собой недели. В данной функции есть возможность преобразования названия столбцов с даты (число и месяц начала недели). То есть неделя N2, N3 в 2017 году представлены как "2 янв, 9 янв". Также значения столбцов представляют собой буквы "у", по которым функция, динамически прогоняясь по столцам, вытаскивает те, чьи значения равны этому "у".
Однако есть недочёт, ибо нужно показывать первое и последнее число отпуска. С первым числом понятно - это начало недели, а вот последнее - это именно последний день последней недели отпуска. Грубо говоря, если у меня стоит буковка с неделях 2 января, 9 января, и это интервал отпуска, то нужно показать именно 2 января, 15 января (то есть начало и конец отпуска). Что нужно изменить в данной функции? Я пытался поменять там дату, приплюсовать 7, но тогда он плюсует всё. И первую неделю и вторую.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create or replace FUNCTION get_week_list3(i_code IN INTEGER, i_year in integer) RETURN VARCHAR2 IS
  l_list  VARCHAR2(32767);
  l_res   VARCHAR2(4000);
BEGIN
SELECT listagg('CASE WHEN '||column_name||' IN(''у'') THEN '||''''|| to_char( trunc (to_date(i_year||'0101', 'yyyymmdd') 
+ ((LTRIM(column_name,'N'))-1)*7, 'ww'), 'dd mon')||''''|| '||''; '' ELSE NULL END ' ,'||') 
WITHIN GROUP(ORDER BY 1)
  INTO  l_list
  FROM  user_tab_columns
  WHERE TABLE_NAME = 'GRAFIK' 
  AND column_name LIKE 'N%';
EXECUTE IMMEDIATE 'SELECT '||l_list||' FROM GRAFIK WHERE kod_sotr=:A AND god=:year' INTO l_res USING i_code,i_year;
RETURN RTRIM(l_res);
END;



Вот вызов
Код: plsql
1.
2.
3.
SELECT t.god, u.FIO, (regexp_substr ( get_week_list3(t.kod_sotr,t.god), '[^;]*;') || 
regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')) as учебный_отпуск FROM GRAFIK t, USERS u 
where t.KOD_SOTR = u.KOD_SOTR;
...
Рейтинг: 0 / 0
Дни отпуска
    #39448765
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Norman94,

шо опять

1) в году не один отпуск
2) отпуск с с декабря по январь

на таких данных ваш вызов неправильно пашет
Код: 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.
SQL> select * from grafik;

       GOD   KOD_SOTR N N N N N N N N N N
---------- ---------- - - - - - - - - - -
      2017        222 у   o o у o у o   o
      2017        202   у o o у o у o   o
      2017        111 o   у у у   у   o

SQL> SELECT t.god, (regexp_substr ( get_week_list3(t.kod_sotr,t.god), '[^;]*;') ||
  2  regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')) as f
  3  FROM GRAFIK t
  4  /

       GOD F
---------- ----------------------------------------
      2017 01 січ; 12 лют;
      2017 08 січ; 12 лют;
      2017 15 січ; 12 лют;

SQL> desc grafik;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 GOD                                                NUMBER(38)
 KOD_SOTR                                           NUMBER(38)
 N1                                                 VARCHAR2(1)
 N2                                                 VARCHAR2(1)
 N3                                                 VARCHAR2(1)
 N4                                                 VARCHAR2(1)
 N5                                                 VARCHAR2(1)
 N6                                                 VARCHAR2(1)
 N7                                                 VARCHAR2(1)
 N8                                                 VARCHAR2(1)
 N9                                                 VARCHAR2(1)
 N10                                                VARCHAR2(1)



зы
1) недель не 52
2) нет order by

......
stax
...
Рейтинг: 0 / 0
Дни отпуска
    #39448773
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax..,

А как должно быть правильно? Это надо вызов функции переправлять?
...
Рейтинг: 0 / 0
Дни отпуска
    #39448776
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stax..Norman94,

шо опять


......
stax

прям с языка снял
...
Рейтинг: 0 / 0
Дни отпуска
    #39448778
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax

И очень странно, что у вас неправильно выводит. У меня так.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create or replace FUNCTION get_week_list3(i_code IN INTEGER, i_year in integer) RETURN VARCHAR2 IS
  l_list  VARCHAR2(32767);
  l_res   VARCHAR2(4000);
BEGIN
SELECT listagg('CASE WHEN '||column_name||' IN(''у'') THEN '||''''||to_char( greatest( trunc (to_date(i_year||'0101', 'yyyymmdd')+((LTRIM(column_name,'N'))-1)*7, 'iw')
,to_date(i_year||'0101', 'yyyymmdd')) ,'dd mon')||''''|| '||''; '' ELSE NULL END ' ,'||')
WITHIN GROUP(ORDER BY 1)
  INTO  l_list
  FROM  user_tab_columns
  WHERE TABLE_NAME = 'GRAFIK' 
  AND column_name LIKE 'N%';
EXECUTE IMMEDIATE 'SELECT '||l_list||' FROM GRAFIK WHERE kod_sotr=:A AND god=:year' INTO l_res USING i_code,i_year;
RETURN RTRIM(l_res);
END;

SELECT t.god, u.FIO, (regexp_substr ( get_week_list3(t.kod_sotr,t.god), '[^;]*;') ||
regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')) as учебный_отпуск FROM GRAFIK t, USERS u 
where t.KOD_SOTR = u.KOD_SOTR;



И вывод на картинке.

У расставлены у 1-5 недель
...
Рейтинг: 0 / 0
Дни отпуска
    #39448779
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax

И очень странно, что у вас неправильно выводит. У меня так.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create or replace FUNCTION get_week_list3(i_code IN INTEGER, i_year in integer) RETURN VARCHAR2 IS
  l_list  VARCHAR2(32767);
  l_res   VARCHAR2(4000);
BEGIN
SELECT listagg('CASE WHEN '||column_name||' IN(''у'') THEN '||''''||to_char( greatest( trunc (to_date(i_year||'0101', 'yyyymmdd')+((LTRIM(column_name,'N'))-1)*7, 'iw')
,to_date(i_year||'0101', 'yyyymmdd')) ,'dd mon')||''''|| '||''; '' ELSE NULL END ' ,'||')
WITHIN GROUP(ORDER BY 1)
  INTO  l_list
  FROM  user_tab_columns
  WHERE TABLE_NAME = 'GRAFIK' 
  AND column_name LIKE 'N%';
EXECUTE IMMEDIATE 'SELECT '||l_list||' FROM GRAFIK WHERE kod_sotr=:A AND god=:year' INTO l_res USING i_code,i_year;
RETURN RTRIM(l_res);
END;

SELECT t.god, u.FIO, (regexp_substr ( get_week_list3(t.kod_sotr,t.god), '[^;]*;') ||
regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')) as учебный_отпуск FROM GRAFIK t, USERS u 
where t.KOD_SOTR = u.KOD_SOTR;



И вывод на картинке.

У расставлены у 1-5 недель
...
Рейтинг: 0 / 0
Дни отпуска
    #39448785
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Norman94stax..,

А как должно быть правильно? Это надо вызов функции переправлять?
я не знаю, могу только догадыватся
если отпусков несколько, напр 3 отпуска то что надо?

......
stax
...
Рейтинг: 0 / 0
Дни отпуска
    #39448794
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stax..Norman94stax..,

А как должно быть правильно? Это надо вызов функции переправлять?
я не знаю, могу только догадыватся
если отпусков несколько, напр 3 отпуска то что надо?

......
stax

А если где-то отгул взял то вообще молодец будет ....

А если одна неделя отпуска?
...
Рейтинг: 0 / 0
Дни отпуска
    #39448796
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax..,

Нет нет, учебный отпуск один. Интервал его обозначается неделями, то бишь N1, N2, N3 и т.д. Они преобразованы в даты, то есть число и месяц начала недели. Как бы круто, но есть изъян - интервал отпуска это 1 и последняя дата, а 1 дата - это начало недели, а последний - это конец, то есть воскресенье последней помеченной "у" недели. И я не знаю как это реализовать.
...
Рейтинг: 0 / 0
Дни отпуска
    #39448798
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MaximaXXL,

Для отгула есть отдельная функция.

А если одна неделя, то её начало и её конец.
...
Рейтинг: 0 / 0
Дни отпуска
    #39448803
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Norman94stax
И очень странно, что у вас неправильно выводит. У меня так.

у сотрудника 111 в 2017 году два отпуска
Код: 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.
SQL> select * from grafik;

       GOD   KOD_SOTR N N N N N N N N N N
---------- ---------- - - - - - - - - - -
      2017        222 у   o o у o у o   o
      2017        202   у o o у o у o   o
      2017        111 o   у у у   у   o
SQL> SELECT t.god, kod_sotr, get_week_list3(t.kod_sotr,t.god) f from grafik t;

       GOD   KOD_SOTR F
---------- ---------- ----------------------------------------
      2017        222 01 січ; 29 січ; 12 лют;
      2017        202 08 січ; 29 січ; 12 лют;
      2017        111 15 січ; 22 січ; 29 січ; 12 лют;


SQL> SELECT t.god, (regexp_substr ( get_week_list3(t.kod_sotr,t.god), '[^;]*;') ||
  2  regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')) as f
  3  FROM GRAFIK t
  4  /

       GOD F
---------- ----------------------------------------
      2017 01 січ; 12 лют;
      2017 08 січ; 12 лют;
      2017 15 січ; 12 лют;



Ваш вызов говорит о другом

.....
stax
...
Рейтинг: 0 / 0
Дни отпуска
    #39448808
123йй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Norman94,

В отпуск только с понедельника(воскреснья) ?
...
Рейтинг: 0 / 0
Дни отпуска
    #39448813
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax..,

Странно. Причём у вас он по воскресениям ищет. В любом случае подскажите как решить мою проблему?
...
Рейтинг: 0 / 0
Дни отпуска
    #39448814
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
123йй,

Да, только с понедельника. А заканчиваться должен в воскресенье.
...
Рейтинг: 0 / 0
Дни отпуска
    #39448823
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Norman94,
если отпуск токо один то два варианта
1) менять ф-цию
2) менять вызов

если 2 то примерно так
1) regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$') в дату
2) +7 дней
3) least
4) опять в DD MON

......
stax
...
Рейтинг: 0 / 0
Дни отпуска
    #39448831
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax..,

Попытался так сделать, неверно.
Код: sql
1.
2.
3.
SELECT t.god, u.FIO, (regexp_substr ( get_week_list3(t.kod_sotr,t.god), '[^;]*;') || 
to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')+7), 'dd.mon')) as учебный_отпуск FROM GRAFIK t, USERS u 
where t.KOD_SOTR = u.KOD_SOTR;


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

Попытался так сделать, неверно.
Код: sql
1.
2.
3.
SELECT t.god, u.FIO, (regexp_substr ( get_week_list3(t.kod_sotr,t.god), '[^;]*;') || 
to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')+7), 'dd.mon')) as учебный_отпуск FROM GRAFIK t, USERS u 
where t.KOD_SOTR = u.KOD_SOTR;


И я не могу понять куда Least вставлять

тогда не там +7 ставишь to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')), 'dd.mon')+7,'dd.mon')
...
Рейтинг: 0 / 0
Дни отпуска
    #39448837
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Norman94,

и на конец года проверить надо
...
Рейтинг: 0 / 0
Дни отпуска
    #39448844
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MaximaXXL,

Код: sql
1.
to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')), 'dd.mon')+7,'dd.mon')



Он на позицию , +7 ругается
...
Рейтинг: 0 / 0
Дни отпуска
    #39448851
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Norman94MaximaXXL,

Код: sql
1.
to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')), 'dd.mon')+7,'dd.mon')



Он на позицию , +7 ругается

попробуй + interval '7' day
...
Рейтинг: 0 / 0
Дни отпуска
    #39448857
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MaximaXXLNorman94MaximaXXL,

Код: sql
1.
to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')), 'dd.mon')+7,'dd.mon')




Он на позицию , +7 ругается

попробуй + interval '7' day

to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')), 'dd.mon')+ interval '7' day)

Ошибка: invalid data type for datatime
...
Рейтинг: 0 / 0
Дни отпуска
    #39448874
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Norman94
to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')), 'dd.mon')+ interval '7' day)

Ошибка: invalid data type for datatime

может тогда правильно писать будем?
Код: plsql
1.
to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')), 'dd.mon')+ interval '7' day,'dd.mon')
...
Рейтинг: 0 / 0
Дни отпуска
    #39448895
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MaximaXXL,

Пробовал, он ругается на запятую
...
Рейтинг: 0 / 0
Дни отпуска
    #39448909
j2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Norman94MaximaXXL,

Код: sql
1.
to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')), 'dd.mon')+7,'dd.mon')



Он на позицию , +7 ругается
4 скобки открыли, 5 закрыли... но при этом без "+7" оно работало. Шайтаны просто :D
...
Рейтинг: 0 / 0
Дни отпуска
    #39448913
Norman94
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
j2k,

Да нет, всё правильно. И при этом он зачем то скобку требует.
Код: plsql
1.
2.
3.
SELECT t.god, u.FIO, (regexp_substr ( get_week_list3(t.kod_sotr,2017), '[^;]*;') ||' - '||
to_char(to_date(regexp_substr ( get_week_list3(t.kod_sotr,t.god), ' [^;]*;$')), 'dd.mon')+ interval '7' day,'dd.mon') as учебный_отпуск FROM GRAFIK t, USERS u 
where u.kod_sotr = 109909 and t.kod_sotr = u.KOD_SOTR and t.god = 2017;
...
Рейтинг: 0 / 0
25 сообщений из 156, страница 1 из 7
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Дни отпуска
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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