1

月と日のみを使用して、重複しない複数の日付期間を定義するテーブルがあります。これは基本的に、季節的なビジネスのために年間を通じてさまざまな量を在庫できるようにする、在庫アイテムの「在庫」テーブルです。以下は、単一のアイテムの在庫テーブルがどのように見えるかの例です。ここには示していない Items テーブルがあることに注意してください。以下の表で、ItemID は外部キー、StockID は主キーです。

StockID    ItemID    BeginDate    EndDate    QtyTrigger    ReorderQty
      1         1         11/1       1/31             0             1
      2         1          2/1       5/31             1             2
      3         1          6/1      10/31             1             1

たとえば、2013 年 1 月 15 日の日付の並べ替えクエリ/レポートを取得したいとします。現在のロジックでは、次のようになるため、クエリが正しく返されません。

SELECT i.*, st.QtyTrigger, st.ReorderQty
FROM t20Itm AS i INNER JOIN t20Itm_Stock AS st ON i.ItemID = st.ItemID
WHERE #01/14/2013# >= CDate(st.BeginDate & "/2013" ) AND
#01/14/2013# <= CDate(st.EndDate & "/2013")
AND i.QtyOnHand <= st.QtyTrigger

問題は、この例の 11/1 の BeginDate が 11/1/2012 である必要があることです。私の例では 2013 を示しています。これは、このクエリを生成するために使用できる唯一のロジックだからです。

ここでの問題はより大きな設計上の欠陥である可能性があると思われるので、これを達成する方法の答え、またはより良いアイデアを探しています。おそらく、この設計が悪い考えである理由があります。

12 月 31 日をまたぐ日付範囲を許可しないことで、これを達成できることはわかっています。ただし、このアプリケーションのユーザーの多くは、11 月から 2 月までの期間が最も遅い月です。1 つは 11 月/12 月用、もう 1 つは 1 月/2 月用です。

データベースには SQL Server を、フロントエンド アプリケーションには MS Access を使用しています。T-SQL または Access VBA を使用できるため、ソリューションはどちらでもかまいません。

4

1 に答える 1

1

私は、この不潔なwhere-clause-hackがそれを行うべきだと信じています:

WHERE 
  ((CDate(st.BeginDate & "/2013" ) <= (CDate(st.EndDate & "/2013" )) 
    AND (#01/14/2013# BETWEEN CDate(st.BeginDate & "/2013" ) AND CDate(st.EndDate & "/2013")))
  OR
  ((CDate(st.BeginDate & "/2013" ) > (CDate(st.EndDate & "/2013" )) 
    AND (#01/14/2013# BETWEEN CDate(st.BeginDate & "/2012" ) AND CDate(st.EndDate & "/2013")))

これら 2 つの OR 式は、年によって異なることに注意してください (2013 対 2012)。begin-end が時系列の場合、最初の式が使用されます (同じ年)。そうでない場合は、2 番目の式が使用されます (昨年で始まり、現在で終わります)。

ただし、これはパフォーマンスが非常に低下する可能性があります。日付を 2 つの別々の列として保存し、これまたは同様のロジックを使用してクエリを実行することをお勧めします。そうして初めて、インデックスを利用できます。

于 2013-08-01T13:52:18.857 に答える