使用MS Access将日期范围拆分为多行

时间:2018-04-13 16:37:28

标签: sql ms-access

我们说我在表中有这些值

Emp_ID |Employee_Name | Start Date | End date 
---------------------------------
A0001  |Adam          |25-03-2018  | 31-03-2018
B0052  |Brad          |28-04-2018  | 30-04-2018

我想编写一个select语句,它应该给我一些结果:

Emp_ID |Employee_Name |  Date | 
---------------------------------
A0001  |Adam          |25-03-2018 
A0001  |Adam          |26-03-2018 
A0001  |Adam          |27-03-2018 
A0001  |Adam          |28-03-2018 
A0001  |Adam          |29-03-2018 
A0001  |Adam          |30-03-2018 
A0001  |Adam          |31-03-2018 
B0052  |Brad          |28-04-2018 
B0052  |Brad          |29-04-2018 
B0052  |Brad          |30-04-2018 

2 个答案:

答案 0 :(得分:1)

一种方法:

有一个单独的表“索引”,它只包含一列(IndexNum)的连续数字(例如0,1,2,3,4,5,6,7,8,9 ....尽可能多的行因为您需要最大可能的日期范围,我会保留一个非常大的表格,其中包含正数和负数,因为两者都很有用。)

创建一个新查询,该查询是Index表和employee表之间的笛卡尔连接。也就是说,两个表都是自己添加的,它们之间没有链接。

如果从Employee表中选择Employee ID,Name和Start Date列,并从Index表中选择IndexNum列,您将获得所有可能的组合 - 或索引表中每行的每个员工的行。现在,只需限制返回哪些索引列 - 在IndexNum上放置一个where子句,这样您只能获得小于结束日期和开始日期之间不同天数的索引行。

伪SQL:

SELECT 
     tbl_Empl.*, tbl_Empl.[Start Date] + IndexNum AS Date 
FROM [Actual Name of Your Employees Table] AS tbl_Empl, 
     [Actual Name of Your Index Table] as tbl_Index 
WHERE 
     tbl_Index.IndexNum >= 0 AND tbl_Index.IndexNum <= (tbl_Empl.[End Date]-tbl_Empl.[Start Date])

您将需要替换您的实际表名,如果您在日期字段中有时间戳,它可能会有点棘手。

答案 1 :(得分:0)

或者,创建一个单独的日期表,其中包含所有员工的范围(例如01/01/2018 - 31/12/2018)。然后运行交叉连接筛选器查询:

SELECT e.[Emp_ID], e.Employee_Name, d.[RangeDate] As [Date]
FROM Employees e, DatesTable d
WHERE d.[RangeDate] BETWEEN e.[Start Date] AND e.[End Date]
ORDER BY e.[Emp_ID], d.[RangeDate]

这是一种在创建一列 DateRange DatesTable 后,在MS Access VBA(使用参数化)中构建此类日期表的方法:

Sub RunDatesLoop()
    Dim strSQL As String
    Dim qdef As QueryDef
    Dim i As Long

    ' PREPARED STATEMENT
    strSQL = "PARAMETERS DateParam Date;" _
               & " INSERT INTO DatesTable (RangeDate) VALUES ([DateParam])"

    Set qdef = CurrentDb.CreateQueryDef("", strSQL)

    For i = 0 To 364
        ' BIND VALUES TO PARAMS AND EXECUTE
        qdef!DateParam = DateAdd("d", i, CDate("01/01/2018"))
        qdef.Execute dbFailOnError
    Next i

    Set qdef = Nothing
    MsgBox "Successfully completed!", vbInformation
End Sub