Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Дни отпуска / 25 сообщений из 156, страница 1 из 7
04.05.2017, 14:37
    #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
04.05.2017, 15:08
    #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
04.05.2017, 15:17
    #39448773
Norman94
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дни отпуска
stax..,

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

шо опять


......
stax

прям с языка снял
...
Рейтинг: 0 / 0
04.05.2017, 15:21
    #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
04.05.2017, 15:21
    #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
04.05.2017, 15:25
    #39448785
stax..
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дни отпуска
Norman94stax..,

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

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

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

......
stax

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

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

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

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

А если одна неделя, то её начало и её конец.
...
Рейтинг: 0 / 0
04.05.2017, 15:36
    #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
04.05.2017, 15:41
    #39448808
123йй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дни отпуска
Norman94,

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

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

Да, только с понедельника. А заканчиваться должен в воскресенье.
...
Рейтинг: 0 / 0
04.05.2017, 15:51
    #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
04.05.2017, 16:04
    #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
04.05.2017, 16:10
    #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
04.05.2017, 16:11
    #39448837
MaximaXXL
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дни отпуска
Norman94,

и на конец года проверить надо
...
Рейтинг: 0 / 0
04.05.2017, 16:18
    #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
04.05.2017, 16:24
    #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
04.05.2017, 16:34
    #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
04.05.2017, 16:54
    #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
04.05.2017, 17:17
    #39448895
Norman94
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дни отпуска
MaximaXXL,

Пробовал, он ругается на запятую
...
Рейтинг: 0 / 0
04.05.2017, 17:38
    #39448909
j2k
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
04.05.2017, 17:45
    #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
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Дни отпуска / 25 сообщений из 156, страница 1 из 7
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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