2012-08-13 86 views
-1

我有如下表:SQL Server的情況下 - 日期

ID ActualDt DueDt  Flag 
-- ------- ------- ----  
1 01/03/12 09/13/12 Y 
2 NULL  07/12/12 Y 
3 NULL  09/12/12 N 
4 02/03/12 01/13/12 N 

我需要標註標誌爲Y以下條件:

1)如果ActualDt不是null DueDt不是null DueDt> ActualDt

2)如果ActualDt爲空和DueDt是基於當前日期過期

否則,標誌= N

注意ActualDt是一個字符串

我怎麼會這個程序在T-SQL

我知道我需要一個case語句。

+0

是DueDt varchar還? – 2012-08-13 21:50:17

+2

爲什麼你將日期存儲爲字符串?那含糊不清的字符串? – 2012-08-13 21:57:51

回答

0

你需要一個更新語句:

update t 
    set flag = (case when ActualDt is not null and DueDt is not null and 
          DueDt > cast(ActualDt as date) 
        then 'Y' 
        when ActualDt is null and DueDt is not null and 
          DueDt > cast(CURRENT_TIMESTAMP as date) 
        then 'Y' 
        else 'N' 
       end) 

這個查詢假設日期的格式數據庫的默認格式相匹配。我的數據庫設置爲美國標準,因此'01/03/12'被解釋爲2012年1月3日。

+0

你不需要IS NOT NULL檢查 - 當你直接引用列時,它們是隱式的。 (DueDt>如果DueDt *或* something爲空,東西永遠不會返回true) – 2012-08-14 12:23:22

+1

@AaronBertrand。 。 。我知道這一點。我把檢查不是空的,所以代碼更明確地說明它在做什麼。 SQL對NULL的處理可能會導致混淆。 – 2012-08-14 13:03:42

+0

好吧,我只是評論,因爲它似乎是多餘的,但我也得到了明確的部分。 – 2012-08-14 13:05:33

2

如果我理解正確的邏輯應該是:

SELECT 
ID, 
ActualDt, 
DueDt, 
CASE 
    WHEN ActualDt IS NOT NULL AND DueDt IS NOT NULL AND DueDt > ActualDt THEN 'Y' 
    WHEN ActualDt IS NULL AND DueDt < getdate() THEN 'Y' 
    ELSE 'N' 
END as Flag 
FROM YourTable 

編輯:亞倫(!像往常一樣)所指出的,我錯過了你正在使用您的日期字符串。既然你是存儲ActualDt爲一個字符串,這不會給你正確的結果

你可以投你的所有日期值日期時間...

SELECT 
ID, 
ActualDt, 
DueDt, 
CASE 
    WHEN cast(ActualDt as datetime) IS NOT NULL AND cast(DueDt as datetime) IS NOT NULL AND cast(DueDt as datetime) > cast(ActualDt as datetime) THEN 'Y' 
    WHEN cast(ActualDt as datetime) IS NULL AND cast(DueDt as datetime) < getdate() THEN 'Y' 
    ELSE 'N' 
END as Flag 
FROM YourTable 

但要知道,這取決於日期格式和您的區域設置(以及dateformat設置),您可能會遇到SQL錯誤或意外的日期。

將日期存儲爲日期時間總是更好 - 你能解釋爲什麼你的日期是字符串嗎?

+0

我也可以顯示其他字段也在相同的選擇 - 如ID等 – 2012-08-13 21:50:14

+0

是的 - 我會更新 – Charleh 2012-08-13 21:50:44

+0

我不相信你可以做一個選擇查詢。 SQl無法識別ActualDt – 2012-08-13 21:56:44

0

爲了讓您的生活更輕鬆,這裏真正的解決方案是stop storing dates as strings。比方說,你開始使用此表開始:

CREATE TABLE dbo.Nathan 
(
ID INT, 
ActualDt VARCHAR(32), 
DueDt VARCHAR(32),  
Flag CHAR(1) 
); 
GO 

INSERT dbo.Nathan VALUES 
(1,'01/03/12','09/13/12','Y'), 
(2, NULL  ,'07/12/12','Y'), 
(3, NULL  ,'09/12/12','N'), 
(4,'02/03/12','01/13/12','N'); 

讓我們先來讓你的字符串完全明確:

UPDATE dbo.Nathan 
    SET ActualDt = CONVERT(CHAR(10), CONVERT(DATETIME, ActualDt, 1), 120), 
     DueDt = CONVERT(CHAR(10), CONVERT(DATETIME, DueDt , 1), 120); 

現在讓我們來更正數據類型:

ALTER TABLE dbo.Nathan ALTER COLUMN ActualDt DATE; 
ALTER TABLE dbo.Nathan ALTER COLUMN DueDt DATE; 
-- you should also update any parameters or code where 
-- explicit types are used to populate these columns 

現在您的數據存儲使用正確的數據類型,並且比較可以在沒有所有這些混亂的字符串解釋和數據類型轉換的情況下工作。您的要求是:

我需要標註標誌爲Y以下條件:
1)如果ActualDt不是null DueDt不是null,DueDt> ActualDt
2)如果ActualDt爲null,並且DueDt基於過去由於當前日期
否則,標誌= N

對我來說,寫爲:

UPDATE dbo.Nathan 
    SET Flag = CASE WHEN DueDt > ActualDt 
    OR (ActualDt IS NULL AND DueDt < CURRENT_TIMESTAMP) 
    THEN 'Y' ELSE 'N' END; 

結果:

ID ActualDt DueDt  Flag 
-- ---------- ---------- ---- 
1 2012-01-03 2012-09-13 Y -- DueDt > ActualDt 
2 NULL  2012-07-12 Y -- past due 
3 NULL  2012-09-12 N -- not past due 
4 2012-02-03 2012-01-13 N -- DueDt NOT > ActualDt 

這,我認爲,比繼續存儲日期字符串更好的方法。