1

我正在尝试根据另一个表中的说明在一个表中生成月度记录。软件 - MS Access 2007,虽然我在这里寻找 SQL 解决方案。为了大大简化问题,假设以下描述了这些表格:

 TaskManager:
  - DayDue
  - TaskName

 Task:
  - DateDue
  - TaskName

所以发生的情况是TaskManager中可能有一个条目{15,“Accounts due”},因此这应该会导致Task表中的“Account due”记录到期日为每月15日。我希望它能为过去几个月和明年创造记录。

我认为我需要做的是首先创建一个 SELECT 查询,该查询会为 TaskManager 表中的每条记录生成 x 条记录,每个月都有一个日期。之后,我执行一个 INSERT 查询,如果记录在上述 SELECT 查询中不存在,则将记录插入到 Task 表中。

我想我可以管理 INSERT 查询,尽管我无法弄清楚如何执行 SELECT 查询。有人可以给我指点吗?

4

3 回答 3

2

您可以使用日历表。

INSERT INTO Task ( DateDue, TaskName )
SELECT calendar.CalDate, TaskManager.TaskName
FROM calendar, TaskManager
WHERE (((Day([CalDate]))=TaskManager.DayDue) 
AND ((calendar.CalDate)<#7/1/2013#));

日历表将仅包含所有日期和其他相关字段,例如工作日 (yesno)。日历表通常非常有用。

于 2012-09-04T12:42:29.700 回答
1

这是我使用 Remou 的日历表想法开发的解决方案。

首先创建一个日历表,它只包含所需范围的所有日期。在 Excel 中制作日期并将其粘贴到表格中很容易。这也是一种非常可靠的方法,因为 Excel 可以正确处理现代日期范围的闰年。

构建此表后,要运行三个查询。第一个是 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);

此方法的一个限制是,如果重复日期(例如每个月的 15 日)发生更改,则将保留错误日期的未来记录。对此的解决方案是使用调整后的日期更新所有未来的记录,然后运行插入。

于 2012-09-13T06:16:59.307 回答
-1

一种可能性是创建一个月份表和一个年份表(上一年、当前和下一年)。我可以运行一个 SELECT 查询,该查询从 TaskManager 表中获取 Day,从 Month 表中获取 Month,从 Year 表中获取 Year——我想这可能会以某种方式为单个 TaskManager 记录创建我想要的多个记录。虽然我不确定确切的 SQL 是什么。

于 2012-09-04T12:29:17.687 回答