Sql 在数据库中存储部分日期

Sql 在数据库中存储部分日期,sql,database-design,schema,Sql,Database Design,Schema,我想在关系数据库(MySQL、PostgreSQL等)中存储部分日期。例如,输入可能只是年份(2013年);年份和月份(2013-08);或年、月、日(2013-08-29)。我不能只使用普通的日期类型,因为年份将扩展到2013-01-01,这与年份、月份和日期没有区别 我曾想过将日期分为三个单独的字段(年、月和日作为整数),但我丢失了DBS中所有的日期细节,不得不管理更多的标记 我的另一个想法是将其存储为日期,并在另一列中说明日期的精确性。例如,“2013-08-01”和“月”意味着日期只能精

我想在关系数据库(MySQL、PostgreSQL等)中存储部分日期。例如,输入可能只是年份(2013年);年份和月份(2013-08);或年、月、日(2013-08-29)。我不能只使用普通的日期类型,因为年份将扩展到2013-01-01,这与年份、月份和日期没有区别

我曾想过将日期分为三个单独的字段(年、月和日作为整数),但我丢失了DBS中所有的日期细节,不得不管理更多的标记

我的另一个想法是将其存储为日期,并在另一列中说明日期的精确性。例如,“2013-08-01”和“月”意味着日期只能精确到该月(2013-08)。”“2013-08-01”和“day”表示日期完全是2013-08-01


最好的方法是什么?

也许最好的方法是将这些时间跨度视为一个
effdate
enddate
。您可以表示所需的任何时间跨度。一年就像“2012-01-01”和“2012-12-31”。单一日期类似于“2013-08-28”和“2013-08-28”


这还将使您能够灵活地扩展表示以处理季度或其他时间组。

根据您指定的内容,您不希望使用
date\u trunc
,因为您希望
2013-08
表示“2013年8月”,而不是实际日期!所以你似乎不太关心瞬间,而更关心周期

我认为你应该只存储字符串。如果您存储:

2013
2013-08
2013-09-25
作为弦,你应该很好。他们都很好。另外,您只需要一列。如果使用两列,数据可能看起来很有趣。例如,如果您存储

2013-09-04  |  MONTH
你可能想知道为什么有
4

同样,我的建议可能会导致字符串格式错误


另一个想法是制作字符串。您的数据库系统甚至可能有时间间隔类型。

我认为有两种可能的方法:

(1)存储日期的子字符串,如:

'2013'               -- year 2013 
'2013-01'            -- year 2013, January
'2013-01-01'         -- year 2013, January 1
(2)存储3个不同的列,年、月、日(您可以毫无疑问地构建索引年+月+日)

哪一个是最好的取决于您希望如何查询数据。假设您有一个存储过程,并且希望传递一个参数,以使所有的行都符合条件

在案例(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建议是一个很好的使用方法。

请输入一些代码。这似乎很讨厌。我想不出一种干净/简单的方法来表示上述数据。您希望运行哪种类型的查询?+1,我很惊讶这不是一个更常见的问题(因此没有比答案中的破解更好的解决方案)。在工作中,我经常(让我烦恼的是)收到第三方的信件,日期如“2019年7月”。我可能会将年份存储为“2012-01-01”(含)至“2013-01-01”独家。一天为“2013-08-28”(含)至“2013-08-29”(不含)。如果将
EndDate
设置为独占,将
StartDate
设置为包含,则可以更轻松地确定日期/时间是否在范围内。存储字符串的问题在于,例如,您无法轻松对其进行算术运算,以查找2013-08和2014-02之间的月数。再说一次,你也不能用其他的方法来做。
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)