1

別のテーブルの指示に基づいて、あるテーブルで月次レコードを生成しようとしています。ソフトウェア - MS Access 2007 ですが、ここで SQL ソリューションを探しています。問題を大幅に単純化するために、次のようにテーブルについて説明するとします。

 TaskManager:
  - DayDue
  - TaskName

 Task:
  - DateDue
  - TaskName

そのため、TaskManager {15, "Accounts due"} にエントリが存在する可能性があるため、Task テーブルに "Account due" レコードが作成され、期日は毎月 15 日になります。過去数か月と来年の記録を作成したいと思います。

私がする必要があると考えているのは、最初に、TaskManager テーブルの各レコードに対して x レコードを生成する SELECT クエリを作成し、各月の日付を指定することです。その後、前述の SELECT クエリに存在しないレコードを Task テーブルに挿入する INSERT クエリを実行します。

INSERT クエリは管理できると思いますが、SELECT クエリの実行方法がわかりません。誰かが私にポインタを与えることができますか?

4

3 に答える 3

1

Remou の Calendar テーブルのアイデアを使用して開発したソリューションを次に示します。

最初に、目的の範囲のすべての日付を単純に含む Calendar テーブルを作成します。Excel で日付を作成し、表に貼り付けるだけで簡単です。これは、Excel が現在の範囲の日付に対してうるう年を正しく処理するため、非常に信頼性の高い方法でもあります。

このテーブルを作成した後、実行するクエリが 3 つあります。1 つ目は SELECT で、日付と頻度に基づいて TaskManager によって生成されたすべての可能なタスクを選択します。このクエリは TaskManagerQryAllOptions と呼ばれ、次のコードがあります。

SELECT TaskManager.ID, Calendar.CalendarDate
FROM TaskManager INNER JOIN Calendar ON
        TaskManager.DateDay = Day(Calendar.CalendarDate)
WHERE (TaskManager.Frequency = "Monthly")
    OR (TaskManager.Frequency = "Yearly" AND
            TaskManager.DateMonth = Month(Calendar.CalendarDate))
    OR (TaskManager.Frequency = "Quarterly" AND
            (((Month(Calendar.CalendarDate)- TaskManager.DateMonth) Mod 3) =  0));

上記の大部分は、四半期ごとの日と月のペアがカバーできるさまざまなオプションをカバーすることです。次のステップは別の SELECT クエリです。これは、日付が必要な範囲内にある TaskManagerQryAllOptions からレコードを選択します。このクエリは TaskManagerQrySelect と呼ばれます。

SELECT TaskManagerQryAllOptions.ID, TaskManager.TaskName,
        TaskManagerQryAllOptions.CalendarDate
FROM TaskManagerQryAllOptions INNER JOIN TaskManager
        ON TaskManagerQryAllOptions.ID = TaskManager.ID
WHERE (TaskManagerQryAllOptions.CalendarDate > Date()-60)
    AND (TaskManagerQryAllOptions.CalendarDate < Date()+370)
    AND (TaskManagerQryAllOptions.CalendarDate >= TaskManager.Start)
    AND ((TaskManagerQryAllOptions.CalendarDate <= TaskManager.Finish) 
            OR (TaskManager.Finish Is Null))
ORDER BY TaskManagerQryAllOptions.CalendarDate;

最後のクエリは INSERT です。このクエリを頻繁に使用するため、重複を生成したくないため、既に作成されたレコードを除外する必要があります。

INSERT INTO Task ( TaskName, TaskDate )
SELECT TaskManagerQrySelect.TaskName, TaskManagerQrySelect.CalendarDate
FROM TaskManagerQrySelect
WHERE Not Exists(
    SELECT *
    FROM Task
    WHERE Task.TaskName = TaskManagerQrySelect.TaskName
        AND Task.TaskDate = TaskManagerQrySelect.CalendarDate);

この方法の 1 つの制限は、繰り返しの日付 (たとえば、毎月 15 日) が変更された場合、間違った日付の将来のレコードが残ることです。これに対する解決策は、調整された日付で将来のすべてのレコードを更新してから、挿入を実行することです。

于 2012-09-13T06:16:59.307 に答える
-1

1つの可能性は、月のテーブルと年のテーブル(前の年、現在、および次の年)を作成することです。TaskManagerテーブルからDay、MonthテーブルからMonth、YearテーブルからYearを取得するSELECTクエリを実行できます。これにより、単一のTaskManagerレコードに対して必要な複数のレコードを作成できると思います。正確なSQLがどうなるかはわかりませんが。

于 2012-09-04T12:29:17.687 に答える