8

所以我在 Access SQL 中做一个项目,它进展顺利。我学到了很多关于 Access 和 VBA 的知识,这个网站在这个过程中很有帮助。

现在我面临一个性能问题,由于我在这种 SQL 工作方面的经验很少,所以我来这里思考一下。

我有一个大约 100 个部分的约 20 个表关系数据库,这些部分代表路线的一部分。Access 数据库本质上是一张地图,我在上面绘制了几条可以动态着色的路线(通过线) - 颜色由特定问题确定并从数据库中计算出来。

这是一张更好地解释它的图片。您不能单击访问中的线条,因此按钮的颜色和宽度设置为与线条相同,并且可以单击以获取更多信息。 一个东西

用户可以选择一个日期,它将根据提出的问题显示路线的进度。到目前为止,这些问题始终是二元的“是或否”(绿色或红色)。

我发现由于查询的复杂性,我几乎必须在启动时为每个查询准备一个临时数据库,否则无法顺利滚动日期。

所以无论如何这是我的具体问题:

路线的每个部分都可以在特定日期处于不同的阶段(想想施工)。从“阶段 0”到“完成”

将实施代表项目阶段的新行。所有部分大约有 8 个可能的阶段,这些阶段可能发生在不同的时间,而且 - 事情就是这样 - 每个部分的顺序不同,并不是所有阶段都发生在所有部分上。

我在数据库中拥有的只是每个阶段的开始日期,而不是结束日期。阶段的顺序几乎由开始日期的顺序决定。至少每个阶段每个部分只能发生一次,所以就是这样。正如你所看到的,对于这种以性能为中心的程序来说,这是一件糟糕的事情。

我确信它将涉及一个或多个临时数据库。我的想法:

  1. 将所有日期聚合到新表的一行中。由于设置了阶段数,因此每个阶段都有列 - 如果需要,何时开始以及何时结束。现在需要一个循环遍历每个并检查用户日期是否属于哪个阶段。所以:“SectionID - phase1needed phase1start phase1end .....”
    优势:

    • 可以手动确认数据并以二级形式很好地显示
    • 它使数据库保持小
      缺点:
    • 实际的循环需要经过(在最坏的情况下)所有阶段才能找到正确的循环。
  2. 计算一个新的数据库,它只是“IdSection - Date - Phase”,并计算每个部分的阶段和间隔中的每一天。
    优势:

    • 这将运行时计算保持为每个部分一个查询
    • 访问应该处理大量数据
      缺点:
    • 我无法手动检查我所做的是否对所有部分都正确
    • 启动时需要很长时间,就像真的很长一样
    • 该数据库中将需要很多条目

现在我问你更喜欢哪个,或者即使有不同的方法?我无法真正改变我拥有的数据点。

简而言之,我必须显示不同阶段的时间间隔,并且在数据库中我只有时间起点,没有完整的阶段顺序。

谢谢你的想法,在这类事情上的任何经验都会有所帮助

4

1 回答 1

1

如果我理解正确,您有一系列类似于表格的数据:

Section 1, Phase 7, Start Date = 11/07/2012
Section 1, Phase 2, Start Date = 12/14/2012
Section 1, Phase 3, Start Date = 12/28/2012
Section 2, Phase 1, Start Date = 11/04/2012
Section 2, Phase 9, Start Date = 12/30/2012
Section 3, Phase 4, Start Date = 11/19/2012
Section 3, Phase 5, Start Date = 12/06/2012
Section 3, Phase 3, Start Date = 12/11/2012

您想回答“2012 年 12 月 15 日每个部分处于什么阶段?”之类的问题,对吗?

在这种情况下,答案应该类似于以下形式:

Section 1, Phase 2
Section 2, Phase 1
Section 3, Phase 3

为此,我假设您有一个名为 SECTION_PHASES 的表,其中包含以下字段:

SECTION    Number
PHASE      Number
START_DATE Date/Time

您需要做的是找出在您当前输入日期之前发生的每个部分的最大开始日期,因为这是在下一个阶段更改之前最近的活动阶段。完成此操作后,您可以将该信息重新加入主表,以确定该日期之后的阶段。

您需要进行一次查询 SECTION_MAX_DATES,然后在其 SQL 视图中包含以下代码:

SELECT [SECTION_PHASES].SECTION, Max([SECTION_PHASES].START_DATE) AS target_date
FROM SECTION_PHASES
WHERE [SECTION_PHASES].START_DATE<#12/15/2012#
GROUP BY [SECTION_PHASES].SECTION
ORDER BY [SECTION_PHASES].SECTION;

保存该查询后,您可以将其作为子查询加入到原始表中。现在,进行另一个查询 SECTION_PHASE_AT_DATE ,其中包括您的原始表和上一个查询,然后在其 SQL 视图中输入以下代码:

SELECT SECTION_PHASES.SECTION, SECTION_PHASES.PHASE, SECTION_PHASES.START_DATE
FROM SECTION_MAX_DATES INNER JOIN SECTION_PHASES ON (SECTION_MAX_DATES.target_date=SECTION_PHASES.START_DATE) AND (SECTION_MAX_DATES.SECTION=SECTION_PHASES.SECTION)
ORDER BY SECTION_PHASES.SECTION;

如果我正确理解您的问题,该查询将为您提供您所追求的结果。如果我正确理解您,给定阶段的新开始日期表示在新日期之前的任何阶段的结束,则无需计算结束日期。

您仍然需要解决一些边缘情况,例如如果某个部分在给定日期之前还没有注册阶段会发生什么。我还将让您弄清楚如何在两个查询中的第一个的 WHERE 子句中参数化日期,考虑到您已经取得的进展,这对您来说可能是微不足道的!但是,我认为这是您为解决问题的数据/计算部分而寻找的 SQL 结构。

于 2013-01-04T22:22:47.467 回答