8

私は Access SQL でプロジェクトを行っていますが、順調に進んでいます。Access と VBA について多くのことを学びましたが、このサイトはその過程で役に立ちました。

今、私はパフォーマンスの問題に直面しています。この種の SQL 作業の経験がほとんどないため、ここに来て考えてみました。

ルートの一部を表す約 100 のセクションに対して、約 20 のテーブル リレーショナル データベースがあります。Access データベースは基本的に、動的に色付けできる複数のルート (線を介して) を描いた地図です。色は特定の質問によって決定され、データベースから計算されます。

これは、それをよりよく説明する写真です。アクセス中の線をクリックすることはできないため、ボタンは色と幅が線と同じになるように設定されており、クリックすると詳細情報が表示されます。 事

ユーザーは日付を選択でき、質問に応じてルートの進行状況が表示されます。これまで、これらの質問は常に「はい」または「いいえ」(緑または赤) の二者択一でした。

クエリが複雑なため、起動時にクエリごとに一時データベースをほとんど準備する必要があることがわかりました。そうしないと、日付をスムーズにスクロールできません。

とにかくここに私の特定の問題があります:

ルートの各セクションは、特定の日付で異なるフェーズ (建設を考えてください) にある可能性があります。「フェーズ 0」から「完了」まで

プロジェクトのフェーズを表す新しい行が実装されます。すべてのセクションには約 8 つのフェーズがあり、異なるタイミングで発生する可能性があり、セクションごとに異なる順序で発生する可能性があり、すべてのフェーズがすべてのセクションで発生するわけではありません。

私がデータベースに持っているのは、各フェーズの開始日のみであり、終了日ではありません。フェーズの順序は、開始日の順序によってほぼ決まります。少なくとも各フェーズは各セクションで 1 回しか発生しないため、それはあります。ご覧のとおり、この種のパフォーマンス中心のプログラムにとって、これはくだらないことです。

1 つまたは複数の一時データベースが含まれることは確かです。私のアイデア:

  1. すべての日付を新しいテーブルの 1 行に集約します。フェーズの数が設定されているため、必要に応じてフェーズごとに列があり、いつ開始し、いつ終了します。ループはそれぞれを通過し、ユーザー日付がどのフェーズに該当するかを確認する必要があります。したがって、「SectionID - phase1needed phase1start phase1end .....」
    利点:

    • データを手動で確認し、二次形式で表示することができます
    • データベースを小さく保ちます
      欠点:
    • 実際のループは、正しいフェーズを見つけるために (最悪の場合) すべてのフェーズを通過する必要があります。
  2. 「IdSection - Date - Phase」だけの新しいデータベースを計算し、間隔内の各セクションと EVERY Day のフェーズを計算します。
    アドバンテージ:

    • これにより、実行時の計算がセクションごとに 1 つのクエリに維持されます
    • アクセスは大量のデータで機能する必要があります
      欠点:
    • 私が行ったことがすべてのセクションで正しかったかどうかを手動で確認することはできません
    • 本当に長いように、起動時に時間がかかります
    • そのデータベースには多くのエントリが必要です

どちらを好むか、または別の方法がある場合でもお尋ねします。私が持っているデータのポイントについては、あまり変更できません。

要するに、さまざまなフェーズの時間間隔を表示する必要があり、データベースには開始時点しかなく、フェーズの完全な順序はありません。

あなたの考えをありがとう、この種の経験は役に立ちます

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

あなたがする必要があるのは、あなたの現在の入力日の前に起こった各セクションの最大開始日を把握することです。それは次のフェーズ変更の前の最も最近のアクティブなフェーズだからです。これを行うと、その情報をメインテーブルに結合して、その日付以降のフェーズを判別できます。

SQLビューに次のコードを含む1つのクエリSECTION_MAX_DATESを作成する必要があります。

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;

私があなたの質問を正しく理解していれば、その質問はあなたが求めている結果をあなたに与えるでしょう。特定のフェーズの新しい開始日が、新しい日付より前に以前に実行されていたフェーズの終了を示していることを正しく理解している場合は、終了日を計算する必要はありません。

特定の日付より前にセクションにフェーズがまだ登録されていない場合にどうなるかなど、解決すべきいくつかのエッジケースがまだあります。また、2つのクエリの最初のWHERE句で日付をパラメータ化する方法を理解するのもあなたに任せます。これは、すでに進歩していることを考えると、おそらく簡単です。ただし、これは、問題のデータ/計算部分を解決するために探していたSQL構造だと思います。

于 2013-01-04T22:22:47.467 に答える