|
|
1
3
这种表在文献中被称为有效的时间状态表。人们普遍认为,每一行都应该通过有一个开始日期和一个结束日期来建立一个周期模型。基本上,SQL中的工作单元是行,一行应该完全定义实体;通过每行只有一个日期,不仅查询变得更复杂,而且您的设计也会因将子原子部分拆分到不同的行而受到影响。 正如欧文·斯穆特所提到的,关于这个问题的权威著作之一是: Richard T.Snodgrass(1999年)。 Developing Time-Oriented Database Applications in SQL 它已经绝版了,但很高兴它可以免费下载pdf(上面的链接)。 我实际上已经阅读了它并实现了许多概念。大部分的文本都是ISO/ANSI标准SQL-92,虽然有些已经用专有的SQL语法实现,包括SQL Server(也可以下载),但我发现概念信息更有用。 Joe Celko还出版了一本书《在集合中思考:SQL中的辅助表、时态表和虚拟表》,很大程度上是从Snodgrass的工作中派生出来的,尽管我不得不说这两个表的分歧在哪里,但我认为Snodgrass的方法更可取。 我同意这些东西很难在我们目前拥有的SQL产品中实现。我们在将数据变为时间之前会考虑很久和困难;如果我们仅仅依靠“历史”就可以摆脱,那么我们会的。SQL Server中缺少SQL-92中的许多临时功能,例如间隔、重叠等。某些基本功能与顺序的“主键”一样,无法使用SQL Server中的检查约束来实现周期不重叠,这就需要触发器和/或UDF。 snodgrass的书是基于他对sql3的研究,这是对标准SQL的一个扩展,目的是为时态数据库提供更好的支持,但遗憾的是,这似乎在多年前就被有效地搁置了:( |
|
|
2
1
当每行都有开始和结束时间时,as-of查询更容易。将结束时间存储在表中是最有效的,但是如果这很困难,您可以按如下方式进行查询:
您可以将此存储在视图中。假设视图称为vwcars,您可以为特定日期选择一辆车,例如:
您可以将其存储在表值存储过程中,但这样做可能会造成严重的性能损失。 |
|
|
3
1
根据您的应用程序的不同,您可能希望将版本控制推送到二级审核表,该表将同时具有开始日期和可以为空的结束日期。我在一个高流量的OLTP中发现,使用版本控制方法可能会变得相当昂贵,如果您的大多数阅读都使用最新版本,那么这可能是有益的。 通过使用开始和结束日期,可以查询辅助表,以查找开始和停止之间或大于开始之间的日期。 |
|
|
4
1
将每种情况的结束时间存储在表中确实使查询更容易表达,但会造成维护完整性规则的问题,例如“同一辆车的两个不同情况(轮/轮)不能重叠”(仍然可以合理地执行)和“任何单个(车/轮)的不同情况的时间序列中不能存在漏洞”/“…)”(再版)。 如果不为每种情况将结束时间存储在表中,则每次需要在只有时间列所隐含的时间间隔上调用Allen运算符(重叠、合并、包含…)时,都会强制编写自联接。 如果需要做这种暂时的事情,SQL只是一场噩梦。 顺便说一句,即使只是用自然语言准确地表述这些查询也是一场噩梦。举例说明:您说过需要“截止”查询,但是您的示例排除了“截止”10:05(Wheelver 3)和10:00(彩色黑色)的情况。尽管事实上,这些情况也“从”09:50开始。 您可能对“时间数据和关系模型”的阅读感兴趣。请记住,这本书中的处理方法是完全抽象的,因为正如书本身所说,“这本书不是关于当今任何地方都可以使用的技术”。 另一本关于这个主题的标准教科书(我被告知)是由势利小人写的,但我不知道书名。我听说这两本书的作者对解决办法持完全相反的立场。 |
|
|
5
1
如果您有两行的同一车辆ID的准确版本时间相同,则此查询将返回重复项,但这需要定义在这种情况下您认为是“最新”的行。我还没有机会测试这个,但我想它会给你你所需要的。至少很近。
|
|
|
Johnny T · 基于当前值的SQL合并表[重复] 10 月前 |
|
John D · 需要为NULL或NOT NULL的WHERE子句 11 月前 |
|
ojek · 如何对SQL结果进行分组和编号? 11 月前 |
|
|
senek · 如何在PL/SQL中将选择结果(列)放入数组中 11 月前 |
|
|
Sax · 规范化Google表格(第一步) 11 月前 |
|
|
BarıŠUÅaklı · 如何在ON冲突更新中使用CTE中的值 11 月前 |
|
|
Jatin · 检索卷计数的动态sql抛出错误语法错误[关闭] 11 月前 |
|
|
Andrus · 如何在sql中查找第二个匹配项 11 月前 |
|
|
Nebula Tech · 在SQL Server中搜索字符串中单词的多次出现 11 月前 |