【问题标题】:Bi-temporal SQL table querying双时态 SQL 表查询
【发布时间】:2020-08-28 02:54:02
【问题描述】:

我正在尝试建模一个 SQL 表来存储员工的工资变化。一种方法是使用如下所示的双时表:

这里有一名员工于 2015 年 10 月 1 日被聘用,工资为 100,000。然后在 2016 年 2 月 15 日,他进行了一次绩效评估,他的老板说:“我们将把你的薪水提高到 110,000,从今年开始(2016 年 1 月 1 日)开始生效。

为了存储这些信息,我使用了两组日期范围。 “有效”告诉您工资何时有效,例如2016 年 1 月 1 日之前为 10 万美元,从那时起为 11 万美元。另一方面,“已结算”范围表示做出决定的时间,在本例中为 2016 年 2 月 15 日。 因此我应该能够查询以下场景:

  • 查看工资审核后的那一刻,他 2015 年 12 月的工资是多少 = 旧工资
  • 他在审核前 2016 年 1 月 2 日的工资是多少 = 旧工资(因为员工还不知道加薪)
  • 审核后他在 2016 年 1 月 2 日的薪水是多少 = 新薪水(因为员工现在知道加薪了)

看来我有两个变量:有效的,和解决的。但是,我正在努力想出一个能够产生正确结果的 SQL 查询。

这是我迄今为止尝试过的(并非适用于所有场景):

SELECT *
FROM Employees 
WHERE (EmployeeId = 10)
 AND 
    (
      ((SettledFrom <= @settledOn) AND (SettledTo IS NULL OR (SettledTo > @settledOn)))
      AND ((EffectiveFrom <= @effectiveOn) AND (EffectiveTo IS NULL OR (EffectiveTo > @effectiveOn)))
    )

理想情况下,我需要一个适用于所有场景并且每次只生成一个结果行的 SQL 查询。 任何帮助是极大的赞赏。 对表格设计的任何改进也是如此。

【问题讨论】:

  • 您使用的是哪种 DBMS 产品? “SQL”只是所有关系数据库都使用的一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加tagWhy should I tag my DBMS
  • 添加了标签。使用 postgreSQL,在某些情况下使用 MS SQL。
  • 目前,您的 To 日期看起来与“下一个”记录的 Froms 相等。你应该决定你的粒度是多少(可能一天是有意义的,而不是更小的一天)然后让每个From 是前面To之后天。
  • “From”是包含的 (>=),而“To”是排除的 (
  • 在 Postgres 中我会使用日期范围:where daterange(effective_from, effective_to, '[)') @&gt; date '2016-01-02';

标签: sql sql-server postgresql temporal bi-temporal


【解决方案1】:

经过进一步调查,我确定我的 SQL 查询确实是正确的。但是,对于完全双时态的场景,我在数据库中丢失了几行。 数据库应该是这样的:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-19
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    相关资源
    最近更新 更多