在SQL Server中存储季度和年份的最佳方法?

时间:2011-04-18 21:42:50

标签: sql-server sql-server-2008 sql-server-2008-r2

在数据库中存储Quarter和Year的最佳方法是什么?我有付款表,我需要分配季度/年,以便很容易判断付款的季度。

我在想:

a)为每笔付款添加两个int列 b)添加另一个表并提前最多5年添加可能的值,并使用该ID将付款加入该表。

还有什么其他选择?也许有些更好或/更容易维护。该数据库将与C#程序一起使用。

8 个答案:

答案 0 :(得分:4)

如果您必须使用单独的年份和季度而不是日期(因为您似乎有特定的报告要求),我会选择tinyint四分之一和smallint一年并存储它们在PAYMENT表本身。

我不会将它存储在另一个表中。这很糟糕,因为:

  • 你必须确保你已经产生了足够的年/季度
  • 您必须加入并使用外键

如果您使用记录存储数据,将有助于提高阅读效果。您的表格可能很小,但始终要记住效果。

WHY

让我们想象你需要得到

  

特定季度的所有付款   付款已超过   具体金额和客户是一个   特定客户

在这种情况下,您需要在所有项目上使用覆盖索引,但仍然没有帮助,因为您的查询是针对特定季度而非季度。但是,将数据放在桌面上将有助于实现更轻松的执行计划。

答案 1 :(得分:3)

我一直只使用日期时间值,1月1日/ 4月/ 7月/ 10月代表每个季度。使计算季度的开始/结束日期变得简单:

  • 开始日期:datetime列本身。
  • 结束数据:dateadd(month,3,quarterColumn)

另一种选择是ISO 8601。以下是用于Internet协议的ISO 8601配置文件:RFC 3339(建议标准)。

2011年每个季度的ISO 8601代表如下:

  • 2011-01-01 / P3M
  • 2011-04-01 / P3M
  • 2011-07-01 / P3M
  • 2011-10-01 / P3M

以上通过开始日期和持续时间(在这种情况下为3个月)指定持续时间。

ISO 8601日期/时间格式的优点是字符串是(A)人类可读,(B)它们正确整理,(C)它们易于解析和(D)它是国际标准。

有些人“延长”ISO 8601的周符号,一年中的一周看起来像2011W32(2011年的第32周)到四分之一符号。使用这种非正式的扩展,2011年的季度看起来像:

  • 2011Q1
  • 2011Q2
  • 2011Q3
  • 2011Q4

答案 2 :(得分:2)

如何根据付款日期使用computed columns?我宁愿这样做也不要让日期和季度/年可能不同步。另一方面,我认为您可能需要能够拥有与日期不同的年份/季度,在这种情况下,您需要将它们分开。我至少考虑使用计算列,因为这似乎是确保完整性的最佳方法。

答案 3 :(得分:1)

对于这么简单的事情,我只保留2个int列,并在需要使用日期范围时使用dateadd建立(关键)日期。

另一个选项是单个日期列,您可以存储该季度的第一天,因此一年中的4个日期将是1月1日,1月4日,1月7日,10月1日。您可以使用datepart Q和Y轻松提取季度,

答案 4 :(得分:1)

两个整数,一年一个,一个四分之一(1-4)。那是你用“a”选项的意思吗?

选项“b”可以使用,但你必须记住每年左右维护一次表。

答案 5 :(得分:1)

我同意两个完成正常。

如果您需要按年份和季度进行排序或过滤,我会添加一个由两列组成的索引。

答案 6 :(得分:1)

你甚至可以使用一个tinyint。它足以以YYQ的形式存储,如111,112,113,114,121 ......几年。

答案 7 :(得分:1)

在数据库中存储季度和年份取决于您的付款数据的组织方式。例子是;插入了多少个不同的付款值。季度/年度范围会有所不同吗?等

“定义”四分之一/年范围的一个好方法是创建一个单独的表,其中“DateTime”字段标识一个季度。您不需要加入表格,只需要在C#中进行编程,以确定范围是否在特定的付费季度内。

例如:

Table 1: Payments
-----------------
paymentID (int)
paymentAmount (double(7,2))
paymentDateTime (DateTime)

Table 2: QuarterYear
--------------------
quarterYearID (int)
dateFrom (date)
dateTo (date)
quarter (tinyint)
description (varchar)

示例数据

paymentID | paymentAmount |   paymentDateTime
------------------------------------------------
    1     |    20.24      |  2011-04-18 08:14:20
    2     |    34.15      |  2011-04-19 07:42:15
    3     |    51.87      |  2011-04-20 13:04:22

quarterYearID |  dateFrom  |   dateTo   | quarter |  description
-----------------------------------------------------------------
      1       | 2011-01-01 | 2011-03-31 |    1    | first quarter
      2       | 2011-04-01 | 2011-06-30 |    2    | second quarter 
      3       | 2011-07-01 | 2011-09-31 |    3    | third quarter
      4       | 2011-10-01 | 2011-12-31 |    4    | forth quarter   

获取“第2季度”所有付款的示例查询 dateValue是来自付款表的动态拉取变量。 C#将处理'dateValue'值。

SELECT quarter FROM QuarterYear WHERE cast('dateValue' AS date) BETWEEN dateFrom AND dateTo;