На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Pr0[)!9Y, Akina, JoeUser
  
> IBExpert. Вычисление среднего значения за час
    Добрый день!
    Подскажите пожалуйста, как в IBExpert сделать процедуру в базе, которая возвращает среднее значение работы сотрудника за час?
    Имеется таблица вида:

    USER_ID T_START T_STOP
    Сотрудник 1 26.03.2018 11:24:11 26.03.2018 11:27:48
    Сотрудник 1 26.03.2018 11:27:53 26.03.2018 11:31:54
    Сотрудник 1 26.03.2018 11:31:54 26.03.2018 11:42:50
    Сотрудник 1 26.03.2018 12:59:00 26.03.2018 13:24:00

    Где T_START - начало работы, T_STOP соответственно конец.

    В итоге нужно получить таблицу следующего вида:

    USER_ID 10:00-11:00 11:00-12:00 12:00-13:00 13:00-14:00 и так до 18:00
    Сотрудник1 0 ~18/60 1/60 24/60
      Делаете опорную таблицу интервалов (почасовую - ну не генерить же её каждый раз), после чего тупо линкуете её с основной по пересечению интервалов, группируете по этим интервалам и работникам и считаете что нужно.
      Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
      Есть претензии ко мне как к участнику? да ради бога.
      Не нравятся мои ответы? не читайте их.
      В общем, берегите себя. Нервные клетки не восстанавливаются.
        Цитата Akina @
        после чего тупо линкуете её с основной по пересечению интервалов

        можно по полкам разложить? Для меня это совсем не тупо)) :wall:
          Есть два отрезка. PeriodStart-PeriodEnd и соответственно HourStart-HourEnd. Связываем строки по наложению этих интервалов друг на друга:
          ExpandedWrap disabled
            FROM Periods p
            JOIN Hours  h ON p.PeriodStart < h.HourEnd AND h.HourStart < p.PeriodEnd
          Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
          Есть претензии ко мне как к участнику? да ради бога.
          Не нравятся мои ответы? не читайте их.
          В общем, берегите себя. Нервные клетки не восстанавливаются.
            Akina Вариант Старт-Стоп в разных таблицах?

            Добавлено
            В IBExpert может это и хороший вариант
            Цель - ничто , процесс - все.
              Да, требуемые периоды группировки в отдельной (динамической либо статической) таблице.

              Добавлено
              Я тут подумал - а у тебя есть на уровне контроля целостности гарантии, что T_START и T_STOP в исходной таблице имеют одинаковую компоненту даты? Если нет - то ведь возможны поганые случаи исходных данных...
              Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
              Есть претензии ко мне как к участнику? да ради бога.
              Не нравятся мои ответы? не читайте их.
              В общем, берегите себя. Нервные клетки не восстанавливаются.
                На текущий момент имею такое решение:
                ExpandedWrap disabled
                  SUM((CASE
                          WHEN EXTRACT(HOUR FROM T1.T_START)<=9 and EXTRACT(HOUR FROM T1.T_STOP)>=9
                          THEN CASE WHEN EXTRACT(HOUR FROM T1.T_START)<9 and EXTRACT(HOUR FROM T1.T_STOP)>9 THEN CAST('10:00:00' AS TIME)-CAST('09:00:00' AS TIME)
                          WHEN EXTRACT(HOUR FROM T1.T_START)<9 THEN CAST(T1.T_STOP AS TIME)-CAST('09:00:00' AS TIME)
                          WHEN EXTRACT(HOUR FROM T1.T_STOP)>9 THEN CAST('10:00:00' AS TIME)-CAST(T1.T_START AS TIME)
                          ELSE CAST(T1.T_STOP AS TIME)-CAST(T1.T_START AS TIME) END
                          ELSE 0
                      END)/60)/60 AS Between09and10,
                   
                  ...
                  ...
                  ...
                   
                    from TABLE1 T1 wt
                   
                      where (T1.state_id = 1) and (
                             cast(T1.T_START as timestamp) < DATEADD(8 HOUR TO DATEADD(1 DAY TO :D)) and
                             cast(T1.T_STOP as timestamp) > DATEADD(8 HOUR TO :D)

                Все считает, но за текущие сутки, а мне нужно с 8 утра выбранного дня (входная переменная :Д) до 8 утра следующего дня. Условие WHERE прописал, но все равно как надо не работает. Нужно вычитать не часы TIME, а даты TIMESTAMP. Попробовал заменить код
                ExpandedWrap disabled
                  CAST(T1.T_STOP AS TIME)-CAST('08:00:00' AS TIME)

                на
                ExpandedWrap disabled
                  CAST(DATEADD(HOUR, -8, T1.T_STOP) AS TIMESTAMP)

                Не запускается процедура, выдает ошибку:
                Цитата
                Strings can not be devided in dialect 3

                Странно, я ж не пытаюсь разделить строку.
                  Вопрос все еще открыт :no-sad:
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script Execution time: 0,1097 ]   [ 18 queries used ]   [ Generated: 15.07.19, 20:14 GMT ]