Первая дата SQL для первого вхождения значения - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть таблица с клиентами и история их рейтинга (низкий, средний, высокий), который оценивается ежеквартально.

Пример таблицы:

client_ID  rating  eff_from
111  high  30.09.2018
111  high  30.06.2018
111  medium  31.03.2018
111  high  31.12.2017
111  high  30.09.2017
111  low  30.06.2017
222  medium  30.09.2018
222  high  30.06.2018
222  high  31.03.2018
222  low  31.12.2017
222  low  30.09.2017
222  medium  30.06.2017

Я хотел бы получитьминимальное значение eff_from от последней оценки.Из приведенной выше таблицы это будет 30.06.2018 для клиента 111 и 30.09.2018 для клиента 222.

Хитрость в том, что рейтинг может измениться, например, с высокого на средний и обратно на высокий, поэтому группировка поклиент и оценка, а также принятие минимальной даты eff_from не работают - это приведет к 30.09.2017 для клиента 111.

Среда является базой данных DB2, а поле eff_from отформатировано как дата.

Есть идеи?

Ответы [ 4 ]

0 голосов
/ 10 декабря 2018

Попробуйте это:

select client_ID, min(eff_from) eff_from
from (
select client_ID, eff_from
, sum(
  case 
  when rating=coalesce(lag(rating) over(partition by client_ID order by eff_from desc), rating) then 0
  else 1
  end
  ) over(partition by client_ID order by eff_from desc) s_
from tab
)
where s_=0
group by client_ID;
0 голосов
/ 10 декабря 2018

Вам нужно условное упорядочение с помощью row_number():

select t.*,
       row_number() over (partition by client_id
                          order by (case when rating = 'low' 
                                         then 1 
                                         else 2
                                    end), eff_from
                         ) as seq
from table t;

Затем, чтобы использовать это в подзапросе и отфильтровать последовательность:

select *
from ( < query > 
     ) t
where seq = 1;

Однако, честно говоря, я не знаю условное упорядочение будет работать или нет? Но это даст представление о том, как сделать иначе, если условное упорядочение не будет работать.

РЕДАКТИРОВАТЬ: Вы также можете использовать оконную функцию, если выше не работает:

 select t.*,
        min(case when rating = 'low' then eff_from end) over (partition by client_id)
 from table t;
0 голосов
/ 10 декабря 2018

Вот один из способов решения вашей проблемы:

CREATE TABLE #T (ClientID INT, RATING VARCHAR (20), eff_From DATE)

INSERT INTO #T VALUES
(111, 'high',  '20180930'  ), 
(111, 'high',  '20180630'  ) ,
(111, 'medium', '20180331' ) ,
(111, 'high',  '20171231'  ) ,
(111, 'high', '20170930'      ) ,
(111, 'low', '20170630'   ); 

WITH CTE AS 
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY ClientID ORDER BY  eff_From) AS RowNumb
    FROM #T
)

SELECT C.*, 
      C2.RATING AS C2Rating,
      C2.eff_From AS C2EffFrom,
      CASE WHEN C.RATING <> C2.RATING THEN 1 ELSE 0 END AS RatingChanged 
INTO #T2
FROM CTE AS C
LEFT JOIN CTE AS C2 ON C.RowNumb = C2.RowNumb - 1

SELECT ClientID, MAX (C2EffFrom) AS MaxEffFrom
FROM #T2
WHERE RatingChanged = 1
GROUP BY ClientID
0 голосов
/ 10 декабря 2018

Это зависит от используемого вами диалекта SQL.В Microsoft Transact-SQL я знаю, что есть структура ROWNUMBER, которая помогает в таких ситуациях.может быть, у вас тоже есть что-то похожее

Пример (T-SQL):

SELECT eff_from FROM
(
    SELECT
        *,
        ROW_NUMBER() OVER(PARTITION BY client_ID ORDER BY eff_from ASC) AS RN
    FROM
        EXAMPLE_TABLE
) TABLE_WITH_RN
WHERE
    RN = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...