2

前提

非常に古い Access 2000 データベースを変更する必要があります。私が持っているのは2つのテーブルです:

製品表:

  • テキストとしての pID - これはキー フィールドです (はい、テキストです。それについては何もできません)
  • 整数としての pLevel - これは製品レベルです: 0=完成、1 から 7=サブ製品
  • pDescription as text - 単なる説明

P アソシエーションテーブル:

  • テキストとしての pIDParent
  • テキストとしての pIDChild

このテーブルが行うことは、(サブ) 製品と他のサブ製品との間の関連付けです。「ルール」は、pIDChild レベルが pIDParent レベルより高くなければならないということです。

次に、特定の pID のすべての子を表示する Form があります。これは、クエリの「チェーン」に基づいています。

これはクエリ q-pAssociation0 で、選択した製品を調べて子を返します。

SELECT DISTINCTROW [t-Associations].pIDParent, [t-Associations].pIDChild, [t-Products].pLevel AS pParentLevel, [t-Products].pLevel AS pChildLevel FROM [t-Products] INNER JOIN [t-Associations] ON [t-Products].pID = [t-Associations].pIDChild
WHERE ((([t-Associations].pIDParent)=[Forms]![fTreeProdotti]![txtProdID]));

次に、7 つのクエリ(q-pAssociation1~q-pAssociation7)があり、それぞれが前のクエリに取り組んでいます。q-pAssociation1 は次のとおりです。

SELECT DISTINCTROW [q-pAssociation0].pIDChild AS pIDParent, [t-Associations].pIDChild, [q-pAssociation0].pChildLevel AS pParentLevel, [t-Products].pLevel AS pChildLevel FROM [q-pAssociation0] INNER JOIN ([t-Products] INNER JOIN [t-Associations] ON [t-Products].pID = [t-Associations].pIDChild) ON [q-pAssociation0].pIDChild = [t-Associations].pIDParent;

最後に、以前のすべてのクエリをグループ化し、フォームのベースとなる GROUP クエリがあります。

質問 クエリがレベル = 親レベル + 1 の子のみを返すように、これをすべて変更する必要があります (したがって、親が子 2 レベル「ダウン」以上を持っている場合、それを返す必要はありません。

したがって、各クエリに条件を追加しました。

SELECT DISTINCTROW [q-pAssociation0].pIDChild AS pIDParent, [t-Associations].pIDChild, [q-pAssociation0].pChildLevel AS pParentLevel, [t-Products].pLevel AS pChildLevel
FROM [q-pAssociation0] INNER JOIN ([t-Products] INNER JOIN [t-Associations] ON [t-Products].pID = [t-Associations].pIDChild) ON [q-pAssociation0].pIDChild = [t-Associations].pIDParent
WHERE ((([t-Products].pLevel)=[q-pAssociation0]![pParentLevel]+1));

しかし、現在、q-pAssociation7 は約 15 レコードを返すのに 10 分を必要としますが、「WHERE」条件がなければ、約 25 レコードをほぼ即座に返します。

この遅いクエリを使用せずに、1 レベル下の製品のみを取得するにはどうすればよいですか?

4

1 に答える 1

1

おそらく、1 レベル離れたすべてのアソシエーションを分離するクエリを作成すると役立つかもしれません...

SELECT a.pIDParent, a.pIDChild, tP.pLevel AS pParentLevel, tC.pLevel AS pChildLevel
FROM ([t-Associations] AS a INNER JOIN [t-Products] AS tP ON a.pIDParent = tP.pID) 
    INNER JOIN [t-Products] AS tC ON a.pIDChild = tC.pID
WHERE (((tC.pLevel)=[tP].[pLevel]+1));

...それを [q-one_level_down] として保存し、それをクエリで使用して、レベルを取得するために Products テーブルを (明示的に) 参照し続ける必要がないようにします。

それを行うと、 [q-pAssociation0] クエリは...

SELECT [q-one_level_down].pIDParent, [q-one_level_down].pIDChild, 
    [q-one_level_down].pParentLevel, [q-one_level_down].pChildLevel
FROM [q-one_level_down]
WHERE ((([q-one_level_down].pIDParent)=[Forms]![fTreeProdotti]![txtProdID]));

...そして(私は信じています)あなたの [q-pAssociation1] クエリは

SELECT [q-one_level_down].pIDParent, [q-one_level_down].pIDChild, 
    [q-one_level_down].pParentLevel, [q-one_level_down].pChildLevel
FROM [q-pAssociation0__NEW_] INNER JOIN [q-one_level_down] 
    ON ([q-pAssociation0__NEW_].pChildLevel = [q-one_level_down].pParentLevel) 
        AND ([q-pAssociation0__NEW_].pIDChild = [q-one_level_down].pIDParent);

このアプローチで目的の結果が得られても、それでも遅すぎる場合は、次の改良として、Append クエリを使用して [q-one_level_down] の結果を、4 つの列すべてにインデックスが付けられたローカル テーブルに永続化します。それを使用します。(その場合、混乱を避けるために [lt-one_level_down] -- 「ローカル テーブル」の「lt」 -- という名前を付けることができます。)

于 2013-04-11T13:41:50.083 に答える