我正在尝试为报告应用程序建模DateRange概念。某些日期范围必须是绝对的,2011年3月1日 - 2011年3月31日。其他日期范围相对于当前日期,过去30天,下周等。在SQL表中存储该数据的最佳方法是什么?
显然对于绝对范围,我可以有一个BeginDate和EndDate。对于相对范围,具有InceptionDate和整数RelativeDays列是有意义的。如何将这两个想法合并到单个表中而不在其中实现上下文,即提及所有四列并使用XOR逻辑来填充4中的2个。
由于具有上下文驱动的列,我拒绝了两种可能的模式:
CREATE TABLE DateRange
(
BeginDate DATETIME NULL,
EndDate DATETIME NULL,
InceptionDate DATETIME NULL,
RelativeDays INT NULL
)
OR
CREATE TABLE DateRange
(
InceptionDate DATETIME NULL,
BeginDaysRelative INT NULL,
EndDaysRelative INT NULL
)
感谢您的任何建议!
答案 0 :(得分:2)
我不明白为什么你的第二个设计不能满足你的需求,除非你处于“从不虚无”的阵营。只需将InceptionDate留给“相对于当前日期”选项,以便您的应用程序可以将它们与固定日期范围分开。
(注意:不知道你的数据库引擎,我在伪代码中留下了日期数学和当前日期问题。另外,在你的问题中,我遗漏了任何文字描述和主键列。)
然后,创建一个这样的视图:
CREATE VIEW DateRangesSolved (Inception, BeginDays, EndDays) AS
SELECT CASE WHEN Inception IS NULL THEN Date() ELSE Inception END,
BeginDays,
EndDays,
FROM DateRanges
或直接从表中选择时使用该逻辑。
你甚至可以更进一步:
CREATE VIEW DateRangesSolved (BeginDate, EndDate) AS
SELECT (CASE WHEN Inception IS NULL THEN Date() ELSE Inception END + BeginDays),
(CASE WHEN Inception IS NULL THEN Date() ELSE Inception END + EndDays)
FROM DateRanges
答案 1 :(得分:1)
其他与当前日期,过去30天,下周等有关。 在SQL表中存储数据的最佳方法是什么?
如果将这些范围存储在表格中,则必须每天更新它们。在这种情况下,您必须每天以不同方式更新每一行。这可能是个大问题;它可能不会。
这种表中通常没有很多行,通常小于50.表结构很明显。更新应该由一个cron作业(或它的等价物)驱动,你应该每天运行非常挑剔的异常报告,以确保事情已经正确更新。
通常情况下,如果一切正常,这些类型的报告都不会产生输出。你有一个额外的复杂性,如果cron没有运行,从cron驱动这样的报告将不会产生输出。那不行。
您还可以创建一个不需要任何维护的视图。有几十行,它可能比物理表慢,但它可能仍然足够快。它消除了这些范围的所有维护和管理工作。 (检查一个一个错误,因为我没有。)
create view relative_date_ranges as
select 'Last 30 days' as range_name,
(current_date - interval '30' day)::date as range_start,
current_date as range_end
union all
select 'Last week' as range_name,
(current_date - interval '7' day)::date as range_start,
current_date as range_end
union all
select 'Next week' as range_name,
(current_date + interval '7' day)::date as range_start,
current_date as range_end
根据应用程序的不同,您可能会以同样的方式处理“绝对”范围。
...
union all
select 'March this year' as range_name,
(extract(year from current_date) || '-03-01')::date as range_start,
(extract(year from current_date) || '-03-31')::date as range_end
答案 2 :(得分:0)
将它们放在单独的表格中。绝对没有理由将它们放在一张表中。
对于相对日期,我甚至可以简单地使表格成为日期函数所需的参数,即
CREATE TABLE RelativeDate
(
Id INT Identity,
Date_Part varchar(25),
DatePart_Count int
)
然后,您可以知道它是-2 WEEK
或30 DAY
方差并在您的逻辑中使用它。
如果你需要同时看到它们,你可以在查询或视图中将它们组合成LOGICALLY,而不需要通过将不同的数据元素塞进同一个表来搞乱你的数据结构。
答案 3 :(得分:0)
创建一个包含begindate和偏移量的表。偏移的精度由您决定。
CREATE TABLE DateRange(
BeginDate DATETIME NOT NULL,
Offset int NOT NULL,
OffsetLabel varchar(100)
)
插入其中:
INSERT INTO DateRange (BeginDate, Offset, OffsetLabel)
select '20110301', DATEDIFF(sec, '20110301', '20110331'), 'March 1, 2011 - March 31, 2011'
过去30天
INSERT INTO DateRange (BeginDate, Duration, OffsetLabel)
select '20110301', DATEDIFF(sec, current_timestamp, DATEADD(day, -30, current_timestamp)), 'Last 30 Days'
稍后显示值:
select BeginDate, EndDate = DATEADD(sec, Offset, BeginDate), OffsetLabel
from DateRange
如果您希望能够解析“原始”模糊描述,则必须寻找“模糊日期”或“近似”功能。 (在git源代码中存在类似this的东西。)