我想在关系数据库(MySQL,PostgreSQL等)中存储部分日期。例如,输入可能只是年份(2013年);年和月(2013-08);或年,月,日(2013-08-29)。我不能只使用正常的DATE类型,因为年份将扩展到2013-01-01,这与年,月和日无法区分。
我想到要么将日期分成三个单独的字段(年,月,日作为整数),但我在DBS中丢失所有日期细节,并且必须管理更多的指标。
我的另一个想法是将它存储为DATE,并有另一个专栏说明日期的精确程度。例如,“2013-08-01”和“月份”表示日期仅精确到月份(2013-08)。 '2013-08-01'和'day'表示日期完全是2013-08-01。
最好的方法是什么?
答案 0 :(得分:2)
也许最好的方法是将这些视为时间跨度并拥有effdate
和enddate
。您可以表示您想要的任何时间跨度。一年就像'2012-01-01'和'2012-12-31'。单个日期将类似于“2013-08-28”和“2013-08-28”。
这也使您可以灵活地扩展表示以处理季度或其他时间组。
答案 1 :(得分: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 = null
,where
子句类似于:
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
的参数,是否要获取其中month = null的行?
另一方面,如果你想通过日期并检查它是否属于日期范围,那么Gordon Linoff建议是一个很好用的建议。
答案 2 :(得分:1)
根据您的指定,您不希望使用date_trunc
,因为您希望2013-08
表示“2013年8月”,而不是实际日期!因此,您似乎不太关心瞬间,而更多关注期间。
我认为你应该存储字符串。如果您存储:
2013
2013-08
2013-09-25
作为字符串你应该没问题。他们排序很好。另外,您只需要一列。如果您使用两列,您的数据可能看起来很有趣。例如,如果您存储
2013-09-04 | MONTH
有人可能想知道为什么4
存在。
然后,根据我的建议,你可能会收到格式错误的字符串。
另一个想法是制作你的字符串ISO 8601 Time intervals。您的数据库系统甚至可能具有时间间隔类型。