2013-07-04 75 views
1

下面是存儲personal_id和日期值的表:排序數據通過SQL語句

Person_ID Effective_Date  End Effective_Date 
    1)6335   24/02/1999 
    2)6335   09/07/1998 
    3)6335   26/06/1998 

和輸出表應該像

Person_ID Effective_Date  End Effective_Date 
    1)6335   24/02/1999   31/12/9999 
    2)6335   09/07/1998   23/02/1999 
    3)6335   26/06/1998   08/07/1998 

,如果我的邏輯會很輕鬆通過使用java代碼更新它。但是可以通過使用SQL語句來完成嗎?我需要有人爲我提供這樣做的邏輯。我目前的結束生效日期將始終是下一個生效日期的前一天。假設我的行號2的生效日期是09/07/1988,那麼行號1的結束生效日期應該是它的前一天(08/07/1988)。儘管我最終生效日期的最後生效日期始終爲31/12/9999。

+4

什麼是烏拉圭回合的最終efeectiveDate邏輯是什麼? –

+1

你可以請我們你在這裏做什麼? – heretolearn

+0

嗨,我只是編輯我的問題,請看看第一。對不起,沒有把問題弄清楚。 – goh6319

回答

1

希望這可以幫助你。運行查詢並檢查結果。

DECLARE @tbl table (ID int, D1 DATETIME, D2 DATETIME) 

INSERT INTO @tbl 
select 1,'2/28/2013','2/28/2013' 
union all 
select 2,'3/2/2013','3/2/2013' 
union all 
select 3,'4/2/2013','4/2/2013' 
union all 
select 4,'4/6/2013','4/6/2013' 
union all 
select 5,'5/21/2013','5/21/2013' 
union all 
select 6,'6/10/2013','6/10/2013' 

SELECT * FROM @tbl 

UPDATE t1 
SET t1.D2= DATEADD(DAY, -1, t2.D2) 
FROM @tbl t1 
    CROSS JOIN @tbl t2 
WHERE t2.D1=(SELECT min(D1) 
       FROM @tbl t 
       WHERE D1>t1.D1) 


SELECT * FROM @tbl 

UPDATE @tbl 
SET D2 = '12/31/9999' 
WHERE D2 = (SELECT TOP 1 D2 FROM @tbl ORDER BY D2 DESC) 

SELECT * FROM @tbl 

這可能不是最有效的情況下,但它假定在D1和D2最初你相同的價值觀。

+0

嗨,夥計,謝謝你的幫助。你的邏輯可以運作良好。但我更喜歡亞歷克斯的答案。無論如何感謝很多。 – goh6319

+0

歡迎傢伙:) – Saksham

0
UPDATE personal_id SET [End Effective_Date] = To_date('31/12/9999', 'dd/mm/yyyy') 
WHERE Person_ID = 6335 AND Effective_Date = To_date('24/02/1999', 'dd/mm/yyyy') 
+0

嗨,夥計,我剛剛編輯我的問題。請先看一看。 (^。^)謝謝。 – goh6319

0

但你必須在EFFECTIVE_DATE的夫婦下一個EFFECTIVE_DATE

SELECT P1.Effective_Date, P2.Effective_Date 
FROM personal_id P1, personal_id P2 where P1.Effective_Date < P2.Effective_Date 
GROUP BY P1.Effective_Date 
HAVING P2.Effective_Date = MIN(P2.Effective_Date) 

我認爲,它必須是一個更好的加入後

: 你就未更新結束生效日期。

+0

嗨katria,如果不提供最終有效性,並且它必須由SQL中的邏輯來控制,這總是在下一個生效日期的前一天? – goh6319

1

可以使用lead功能提前尋找到下一行,並得到其有效日期:

select person_id, effective_date, 
    lead(effective_date) 
    over (partition by person_id order by effective_date) as lead_date 
from t42; 

PERSON_ID EFFECTIVE_DATE LEAD_DATE 
---------- -------------- --------- 
     6335 26-JUN-98  09-JUL-98 
     6335 09-JUL-98  24-FEB-99 
     6335 24-FEB-99 

然後,您可以用它來執行更新。該merge命令使這很簡單:

merge into t42 
using (
    select person_id, effective_date, 
    lead(effective_date) 
     over (partition by person_id order by effective_date) as lead_date 
    from t42 
) t 
on (t42.person_id = t.person_id and t42.effective_date = t.effective_date) 
when matched then 
update set t42.end_effective_date = 
    case 
    when t.lead_date is null then date '9999-12-31' 
    else t.lead_date - 1 
    end; 

3 rows merged. 

select * from t42; 

PERSON_ID EFFECTIVE_DATE END_EFFECTIVE_DATE 
---------- -------------- ------------------ 
     6335 26-JUN-98  08-JUL-98   
     6335 09-JUL-98  23-FEB-99   
     6335 24-FEB-99  31-DEC-99   

using條款從上面從上一行得到最新片段。 on子句將其與原始表匹配,並且匹配的行將結束生效日期更新爲領導生效日期前一天,或者如果沒有前導值(對於最近的「當前」行)使用固定從1999年

你的問題日期提到了一個更新,但如果你只是想結束日期爲您的結果計算列設置它的簡單得多:

select person_id, effective_date, 
    case when lead_date is null then date '9999-12-31' 
    else lead_date - 1 end as end_effective_date 
from (
    select person_id, effective_date, 
    lead(effective_date) 
     over (partition by person_id order by effective_date) as lead_date 
    from t42 
); 

PERSON_ID EFFECTIVE_DATE END_EFFECTIVE_DATE 
---------- -------------- ------------------ 
     6335 26-JUN-98  08-JUL-98   
     6335 09-JUL-98  23-FEB-99   
     6335 24-FEB-99  31-DEC-99   
+0

嗨,你剛剛寫的SQL語句讓人印象深刻。它真的幫了我很大的忙,指令很清楚。你爲我提供了一個明確的方向。非常感謝你。 – goh6319