SQL的第一个日期第一次出现的值

时间:2018-12-10 14:50:44

标签: sql db2 grouping

我有一张与客户有关的表格以及他们的评分历史(低,中,高),每季度进行一次评估。

示例表:

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日期。在上表中,客户端111的日期为2018年6月30日,客户端222的日期为2018年9月30日。

诀窍是,评级可能会发生变化,例如从高到中,然后再回到高,因此按客户和评级进行分组并采用最小eff_from日期是行不通的-客户端111的结果为30.09.2017。

该环境是一个DB2数据库,并且eff_from字段的格式设置为日期。

有什么想法吗?

4 个答案:

答案 0 :(得分:1)

这取决于您使用的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

答案 1 :(得分:1)

这是解决问题的一种方法:

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

答案 2 :(得分:0)

您需要使用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;

答案 3 :(得分:0)

尝试一下:

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;