Выберите даты PERIOD_BEGIN и PERIOD_END из исторических данных, содержащих только метку времени в Oracle SQL - PullRequest
0 голосов
/ 15 ноября 2018

Я столкнулся с небольшой проблемой.Справочная информация: я работаю в качестве финансового контролера в финансовом учреждении, которое предлагает услуги по управлению активами, и мне приходится составлять внутреннюю отчетность о приходе и уходе евро.Поскольку это один из KPI, используемых для оценки эффективности работы менеджеров, я должен иметь возможность сообщать эти цифры на каждого менеджера.Этот бит прост, поскольку каждому клиенту назначен менеджер.Теперь самое интересное - некоторые сомнительные варианты дизайна DW были сделаны в прошлом, а в таблице, содержащей отношения менеджер / клиент, отсутствует вся соответствующая временная информация, такая как «действителен с» или «действителен до».В основном это просто хранит текущее состояние.Иногда клиенты и портфели передаются другим менеджерам, и это приводит к тому, что все транзакции, совершенные во время правления старого менеджера, отображаются как принадлежащие новому менеджеру.

Например, менеджер Джо управляет клиентом Blammo Ltd с января поМарт и клиент подписывает средства на 10 миллионов долларов.Джо покидает компанию, и клиент назначается менеджером Хелен.В течение апреля клиент снимает 5 мил.Когда я собираю свои отчеты в конце апреля, KPI Джо читает + -0, в то время как Хелен показывает +5 миллионов, хотя по правде говоря, Джо заработал 10 миллионов, а Елена потеряла 5.

У нас есть таблица аудитаон содержит все строки таблицы, содержащие отношения менеджер / клиент, и каждая строка имеет временную метку, когда она была создана.Я надеюсь достичь представления, использующего эти временные метки для построения таблицы с датами VALID_FROM и VALID_UNTIL , чтобы можно было легко назначать транзакции отдельным менеджерам, присоединяясь к транзакции.между ДЕЙСТВИТЕЛЬНЫМИ датами.

Так что в основном у меня есть ...

  CUSTOMERID   MANAGERID   TIMESTAMP   
 ------------ ----------- ------------ 
           1   A           01-01-2018  
           1   B           28-02-2018  
           1   A           31-05-2018  
           1   C           31-08-2018  

И что мне нужно ...

  CUSTOMERID   MANAGERID   VALID_FROM   VALID_UNTIL  
 ------------ ----------- ------------ ------------- 
           1   A           01-01-2018   28-02-2018   
           1   B           28-02-2018   31-05-2018   
           1   A           31-05-2018   31-08-2018   
           1   C           31-08-2018  

То, что я попробовал, это

SELECT
    CUSTOMERID,
    MANAGERID,
    MIN(TIMESTAMP) AS VALID_FROM,
    MAX(TIMESTAMP) AS VALID_UNTIL
FROM CUSMAN.CUS_MAN_AUDIT
GROUP BY
    CUSTOMERID,
    MANAGERID

, и это сработало бы в случае, когда клиенты никогда не переназначаются на предыдущего менеджера.Однако из-за отпусков по материнской линии и т. Д. Клиенты распределяются между менеджерами туда и обратно, поэтому приведенное выше решение не даст правильного результата - объединение транзакции, сделанной клиентом «1» в «30 -04-2018», с отношениями клиент / менеджерданные дадут два результата - оба менеджера A и B. Ниже приведена таблица, которая выдаст приведенный выше запрос.

  CUSTOMERID   MANAGERID    VALID_FROM    VALID_UNTIL  
 ------------ ----------- -------------- ------------- 
           1   A           01-01-2018     31-08-2018   
           1   B           28-02-2018     31-05-2018   
           1   C           31-08-2018                  

Такое ощущение, что есть простой способ сделать это, но я в тупике.Есть идеи?

РЕДАКТИРОВАТЬ

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

+------------+-----------+------------+-------------+--------------+ | CUSTOMERID | MANAGERID | VALID_FROM | VALID_UNTIL | CUSTOMERNAME | +------------+-----------+------------+-------------+--------------+ | 1 | A | 01-01-2018 | 02-01-2018 | Blam-O Litnd | | 1 | A | 02-01-2018 | 15-01-2018 | Blamo Litd | | 1 | A | 15-01-2018 | 28-02-2018 | Blammo Ltd | +------------+-----------+------------+-------------+--------------+

, в то время как это должно (или, по крайней мере, что я хотел быэто)

+------------+-----------+------------+-------------+ | CUSTOMERID | MANAGERID | VALID_FROM | VALID_UNTIL | +------------+-----------+------------+-------------+ | 1 | A | 01-01-2018 | 28-02-2018 | +------------+-----------+------------+-------------+

И я не могу вспомнить, как я отформатировал свои таблицы в исходном сообщении, извините ...

1 Ответ

0 голосов
/ 15 ноября 2018

Вы можете сделать это с помощью оконной функции, которая получает LEAD (следующее) значение даты для каждого клиента, упорядоченное по отметке времени

SELECT
    CUSTOMERID,
    MANAGERID,
    TIMESTAMP AS VALID_FROM,
    LEAD(TIMESTAMP) OVER(PARTITION BY CUSTOMER ORDER BY TIMESTAMP) as VALID_TIL
FROM CUSMAN.CUS_MAN_AUDIT

Если это помогает вашему пониманию, это функционально похоже на это:

SELECT
    CUSTOMERID,
    MANAGERID,
    cur.TIMESTAMP AS VALID_FROM,
    MIN(nxt.TiMESTAMP) as VALID_TIL
FROM 
  CUSMAN.CUS_MAN_AUDIT cur
  LEFT OUTER JOIN 
  CUSMAN.CUS_MAN_AUDIT nxt
  ON
    cur.CUSTOMERID = nxt.CUSTOMERID AND
    cur.TIMESTAMP < nxt.TIMESTAMP
GROUP BY
    CUSTOMERID,
    MANAGERID,
    cur.TIMESTAMP

Присоединение таблицы к себе на том же клиенте, но где каждая запись cur связана с каждой записью, имеющей более позднюю дату (nxt), и затем получает МИНУС более поздних дат ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...