2013-05-02 39 views
2

假設表格如下:如何查詢幾個可能空白的日期字段的最早日期?

+----+----------+-----------+----------+ 
| ID | date1 | date2 | date3 | 
+----+----------+-----------+----------+ 
| 1 | 3/2/2013 | 5/6/2013 |   | 
| 2 |   | 12/1/2011 | 6/5/2010 | 
| 3 | 1/1/1936 | 1/5/1936 | 1/9/1945 | 
| 4 | 2/1/2014 |   |   | 
+----+----------+-----------+----------+ 

我想返回各行的最早日期的查詢。至少有一個日期列將被填充。

我已經試過:

SELECT id, 
iif(date1<date2 and date1<date3, 
    date1, 
    iif(date2<date1 and date2<date3, 
     date2, 
     date3)) as dateEarliest 
FROM tbl; 

但似乎如果date3是最早這隻返回正確的結果;否則它返回一個空白。

+1

當涉及NULL時,MS Access如何處理'<'?我希望能夠在沒有任何NULL值的所有記錄上正常工作。 – user2246674 2013-05-02 19:19:27

回答

2

您無法與NULL值進行比較。使用Nz函數將NULL轉換爲您可以比較的值。 Nz的語法是:Nz (variant, [ value_if_null ])

所以你使用這樣的:

iif(Nz(date1,#1/1/2999#) < Nz(date2,#1/1/2999#) and Nz(date1,#1/1/2999#) < (Nz(date3,#1/1/2999#) 

如果這是在Access中使用,你知道VBA,你還可以創建返回所需的值的函數。這可能會更整潔,因爲它看起來像:

Select id, LowDate([date1],[date2],[date3]) as dateEarliest 

這是一個函數,應該爲你工作。

Function LowDate(D1, D2, D3) 
    D1 = Nz(D1, #1/1/2999#) 
    D2 = Nz(D2, #1/1/2999#) 
    D3 = Nz(D3, #1/1/2999#) 
    If D1 < D2 And D1 < D3 Then 
     LowDate = D1 
    ElseIf D2 < D1 And D2 < D3 Then 
     LowDate = D2 
    Else 
     LowDate = D3 
    End If 
End Function 
+0

+1但是,這個答案似乎意味着'Nz()'總是返回一個字符串,這是一個誤導。 – HansUp 2013-05-03 00:29:17

+0

我的第一個答案在null上返回了一個日期,但在我的快速測試中,它不喜歡Nz([date1],#1/1/2099#),所以我改變了我的答案。但在再次測試中,我發現它很有用。之前必須有錯別字。 – 2013-05-03 00:52:22

+0

我希望你的答案更多沒有所有'CDates',但這是一個小問題,並不足以阻止我的upvote。我擔心的是,第一段可能被誤解爲「Nz()只返回字符串」。 – HansUp 2013-05-03 01:21:26

4

這可能不是「最好」的方式做到這一點,但要做到這將是逆轉置數據的一種方式,所以它看起來是這樣的:

id date 
1 
1 3/2/2013 
1 5/6/2013 
2 
2 6/5/2010 
2 12/1/2011 
3 1/1/1936 
3 1/5/1936 
3 1/9/1945 
4 
4 2/1/2014 

這可以像做所以:

SELECT id, date1 from tbl 
UNION 
SELECT id, date2 as date1 from tbl 
UNION 
SELECT id, date3 as date1 from tbl 

(注意:我命名日期字段日期1,因爲日期是保留關鍵字。)

從這裏,你可以使用集合功能,如分:

select id, min(date1) as dateEarliest 
from (SELECT id, date1 from tbl 
UNION 
SELECT id, date2 as date1 from tbl 
UNION 
SELECT id, date3 as date1 from tbl) unpivottbl 
group by id; 

哪個會給你你想要的。

1

我想你可以修改iif聲明是這樣的:

SELECT id, 
iif((date1<date2 and date1<date3) or (date1 < date2 and date3 is null) or (date1 < date3 and date2 is null), 
    date1, 
    iif(date2<date1 and date2<date3) or (date2 < date1 and date3 is null) or (date2 < date3 and date2 is null), 
     date2, 
     date3)) as dateEarliest 
FROM tbl; 

此,如果您的空白是NULL會工作。