2013-08-29 56 views
7

我想在關係數據庫(MySQL,PostgreSQL等)中存儲部分日期。例如,投入可能只是一年(2013年);年和月(2013-08);或年,月,日(2013-08-29)。我不能只使用正常的DATE類型,因爲年份將擴大到2013-01-01,並且這與年份,月份和日期沒有區別。將部分日期存儲在數據庫中

我想過要麼將日期分成三個單獨的字段(年,月,日作爲整數),但我在DBS中丟失了所有日期的細節,並且必須管理更多的指示。

我的另一個想法是將它作爲日期存儲,並有另一列說明日期的精確程度。例如,'2013-08-01'和'月'意味着該日期僅在該月份(2013-08)精確。 '2013-08-01'和'日'意味着日期完全在201​​3-08-01。

這樣做的最好方法是什麼?

+0

請輸入一些編碼。 –

+0

這似乎是icky。我想不出一種簡潔的方式來表示數據。 – user2246674

+0

你想運行什麼樣的查詢? –

回答

2

我認爲是有兩種可能的方式去:

(1)商店子日期,如:

'2013'    -- year 2013 
'2013-01'   -- year 2013, January 
'2013-01-01'   -- year 2013, January 1 

(2)商店3不同的列,年,月,日(你可以建立年份+月份+日期而沒有問題)

2013 null null  -- year 2013 
2013  1 null  -- year 2013, January 
2013  1  1  -- year 2013, January 1st 

哪一個最好取決於你想如何查詢數據。假設你有存儲過程並且你想傳遞一個參數來讓所有的行都進入狀態。

如果(1),你傳遞字符串@Date = '2013-01'作爲參數,你想獲得的所有行一年= 2013和月= 01所以where條款是這樣的:

where left(Date, len(@Date)) = @Date 

如果(2),您通過三個參數 - @Year = 2013, @Month = 1, @Day = nullwhere條款是這樣的:

where 
    Year = @Year and -- Supposing @Year is always not null 
    (@Month is null or @Month is not null and Month = @Month) and 
    (@Day is null or @Day is not null and Day = @Day) 

根據您想要如何處理行,這可能會更復雜。例如,如果您提供像2013-01這樣的參數,那麼您是否想要在月份= null或不在的行?另一方面,如果你想通過日期並檢查它是否落入日期範圍內,那麼Gordon Linoff的建議是一個很好的使用方法。

+0

+1用於考慮如何查詢這些數據。 –

2

也許最好的辦法是將這些視爲時間跨度,並有effdateenddate。你可以代表你想要的任何時間跨度。一年將會像'2012-01-01'和'2012年12月31日'。單個日期將如'2013-08-28'和'2013-08-28'。

這也可以讓您靈活地擴大代表處理宿舍或其他時間組。

+0

如果OP想檢查日期範圍內的+1,那麼可以使用 –

+0

我可能會將一個年份存儲爲「2012-01-01」(含)至「2013-01-01」獨佔。一天的「2013-08-28」(含)至「2013-08-29」(不含)。如果您將'EndDate'排除在外並且'StartDate'包含在內,則可以更輕鬆地確定日期/時間是否在範圍內。 –

+0

@WW。好點 –

1

根據您的指定,您不希望使用date_trunc,因爲您想讓2013-08表示「2013年8月份」,而不是實際的日期!所以你似乎很少關心瞬間,以及更多關於時間段

我想你應該只是存儲字符串。如果你存儲:

2013 
2013-08 
2013-09-25 

作爲字符串,你應該沒問題。他們排序很好。另外你只需要一列。如果你使用兩列,你的數據可能看起來很有趣。舉例來說,如果你存儲

2013-09-04 | MONTH 

人們可能會問,爲什麼4是存在的。

然後再次,您可能會得到一個格式錯誤的字符串與我的建議。

另一個想法是讓你的字符串ISO 8601 Time intervals。你的數據庫系統甚至可能有一個時間間隔類型。

+0

存儲字符串的麻煩在於,例如,您無法輕鬆對它們進行算術運算,以查找2013-08與2014-02之間的月數。再次,你不能用大多數其他的替代品來做到這一點。 –