簡體   English   中英

SQL的第一個日期第一次出現的值

[英]SQL first date for the first occurrence of a value

我有一張與客戶的表格以及他們的評分歷史(低,中,高),每季度進行評估。

表格示例:

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為30.09.2018年。

訣竅是評級可能會發生變化,例如從高到中,然后再變回高,因此按客戶和評級進行分組並采用最小的eff_from日期是行不通的-客戶端111的結果為30.09.2017。

該環境是一個DB2數據庫,並且eff_from字段的格式設置為日期。

有任何想法嗎?

這取決於您使用的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

這是解決您的問題的一種方法:

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

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

嘗試這個:

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM