我有一个要存储在数据库中的书籍列表。其中一个属性是该书首次出版的日期。在较旧的书籍(超过 100 年)中,我通常只知道十年(如 185X),或者如果是非常古老的书籍,则只知道世纪(如 15XX)。
您将如何将这些日期保存在 datetime2 字段中?15XX 等于 1500?例如,我希望能够查询超过一百年的书籍。所以我想以某种方式将这些值存储为有效的 datetime2 值。有什么建议吗?15XX 作为 '1500-01-01 00:00' 对我来说似乎是合理的。这种方法有什么缺点吗?
唯一的缺点是当有人要求所有从 1550 年到 1650 年出版的书籍时。你的 15XX 变成了 1500,所以它不会包含在他的结果中。
当给定的书出版时,你真正拥有的是一段不确定的时期。我会存储 2 个日期:一个是期间开始时,另一个是结束时。现代书籍会将其设置为相同的日期,但最旧的书籍可以存储为 1500-01-01 00:00 - 1599-12-31 23:59
当然,这会使选择复杂化。你必须决定它是否值得。你可以宣称要求“1550 到 1650”是愚蠢的。
作为@dragon112 答案的扩展,您是否有可能需要15XX
前两个选项中的两个选项? (就像 NULL 是和不是任何值一样,同时。)
如果是这样,您可以存储两个日期并确定图书出版的日期范围。
这确实使您的查询/系统更加复杂。在编写这些 SQL 机器人时,它们在语法上是正确的,但您需要在任何给定情况下选择合适的,因为它们可能会给出不同的结果......
WHERE
earliestPublishDate > '1550-01-01'
WHERE
latestPublishDate > '1550-01-01'
因此,在确定如何存储数据时最重要的问题是:
- 您将如何查询它?
您需要了解您的用例(或可能的用例)才能确定正确的数据表示。
在我看来,有 3 种方法可以保存此类书籍的日期:
这些方法与代码本身无关,但是当您查询某个年龄时,它们会影响您的结果。所以在我看来,任何对你来说感觉最好的东西都应该没问题。
换句话说,当你查询一本 500 年的书时,你想得到一本 15xx 年的书吗?因为现在是 2012 年,所以数据库不会返回这本书 (2012 - 500 = 1512)。
有趣的问题,我会考虑以下解决方案:
将值保存为数据库中的两个字段。第一个以您提到的“1500-01-01 00:00”格式存储,用于排序。第二个字段用于记录原始值15XX,其数据类型为字母数字类型。
使用这种方法,您不会丢失数据未知的事实。但是您仍然满足搜索某个日期之前的书籍的要求。
然后,日期时间字段严格根据字母数字字段计算得出。
如果您不需要使用日期存储时间,则使用数据类型“日期”,无需使用 datetime2 来仅允许从 01-01-0001 开始的日期。
日期还支持从 0001-01-01 到 9999-12-31 的日期。Datetime2 比 datetime 具有更高的时间精度。
DECLARE @var VARCHAR(100)
SET @var = ''
SET @var = CASE LEN(@var)
WHEN 1 THEN @var + '000'
WHEN 2 THEN @var + '00'
WHEN 3 THEN @var + '0'
ELSE @var
END
SELECT CAST(@var AS DATE)