从开始和结束时间字段导出两个小时的时间块

Derive two hours time blocks from start and end time fields

我在 Microsoft Access 中有一个 table,其中包含一个活动的志愿者列表。 table 包含名称、phone 号码等字段。还有三个附加字段;描述 activity 志愿者将被分配到的任务。例如停车场、正门、售票亭等。另外两个字段,开始和结束时间描述了志愿者什么时候可以工作。

是否可以编写一个查询 - 也许是某种枢轴 table - 有 2 小时的时间段作为行 header 和某种 true/false 值,如果分配的时间段已满?活动时间是早上 6 点到下午 6 点。

例如:

Assignment | 0600 | 0800 | 1000 | 1200 | 1400  | 1600 
Parking    |  X   |  o   |   X  |  X   |   X   |   X  
TicketBooth|  o   |  o   |   X  |  o   |   X   |   o  

我正在尝试按任务对志愿者进行分组,并从每个志愿者的开始和结束时间得出两个小时的时间段,并生成一份报告,使活动协调员能够轻松区分他们是否需要添加一个志愿完成任务。

志愿者table结构如下:

FirstName | LastName | Assignment   | StartTime | EndTime
Joe       | Smith    | Parking      | 1000      | 1800
Jessica   | Anderson | Parking      | 0600      | 0800
Ryan      | Webber   | TicketBooth  | 1000      | 1200
Michael   | Flent    | TicketBooth  | 1400      | 1600

在给定 table 结构的情况下,是否可以生成查询以获取上述示例中显示的结果?如果没有,我需要修改什么?

好的,鉴于您的示例数据,数据透视表 table 并不理想,因为缺少 table/join table 以及时间和谁可以在何时工作等

因此,我创建了一个 returns "o""x" 的函数,具体取决于某人的空闲时间是否适合您向我们提供示例的时间段。唯一不好的是你必须为每个时间段手动创建一个列。如果有 Pivot table.

那就太好了

这也可以使用 IIf() 来完成。这是一个简单的例子:

SELECT volunteers.Names,
       volunteers.Assignment, 
       IIf(1800>=[Start] And 1800<=[End],"Can Work","Can't") AS 1800
FROM volunteers;

无论如何,这是函数(我没有处理任何错误):

Option Compare Database
Option Explicit

Public Function IsAvailable(time, starttime, endtime) As String

Dim AvailableTime, StartingTime, EndingTime As Integer

AvailableTime = time
StartingTime = starttime
EndingTime = endtime

If AvailableTime >= StartingTime And AvailableTime <= EndingTime Then
    IsAvailable = "o"
Else
    IsAvailable = "x"
End If

End Function

如何在查询中使用它:

SELECT volunteers.Names, 
       volunteers.Assignment, 
       IsAvailable(600,[Start],[End]) AS 0600, 
       IsAvailable(800,[Start],[End]) AS 0800, 
       IsAvailable(1000,[Start],[End]) AS 1000, 
       IsAvailable(1200,[Start],[End]) AS 1200, 
       IsAvailable(1400,[Start],[End]) AS 1400, 
       IsAvailable(1600,[Start],[End]) AS 1600, 
       IsAvailable(1800,[Start],[End]) AS 1800
FROM volunteers;

可视化:

注意:我在 table 中使用 StartEnd 作为我的列名称,因此您必须更改 [Start][End],分别。

此外,我个人认为这不是最佳解决方案。我想如果你知道这些数据必须采用这种格式,我可能会为此设计我的数据库,但这是一种粗略的解决方法。

我制作了一个时间块 table,其中 Date/Time 字段用于开始和结束 每个块。然后 CROSS JOIN 使用包含志愿者分配的 table 对其进行编辑,并将其用作交叉表查询的数据源。

这是下面查询的结果集...

备注:

  1. 我在预定的时间块中使用了一个数字(而不是 "X")。如果您有不止一名志愿者同时安排了同一任务……无论是有意还是无意,这可能会有用。
  2. 在我的作业table中,StartTimeEndTime都是Date/Time 数据类型。如果您的是文本,这种通用方法仍然有效,但您必须调整查询。

这是查询...

TRANSFORM Count(q.block_start) AS CountOfBlock_start
SELECT q.Assignment
FROM
    (
        SELECT a.Assignment, tb.block_start
        FROM assignments AS a, time_blocks AS tb
        WHERE
                tb.block_start >= [a].[StartTime] 
            AND tb.block_end   <= [a].[EndTime]
    ) AS q
GROUP BY q.Assignment
PIVOT Format(q.block_start, 'hhnn')
    IN ('0600','0800','1000','1200','1400','1600');

这是我的 time_blocks table ...

block_start block_end
----------- -----------
 6:00:00 AM  8:00:00 AM
 8:00:00 AM 10:00:00 AM
10:00:00 AM 12:00:00 PM
12:00:00 PM  2:00:00 PM
 2:00:00 PM  4:00:00 PM
 4:00:00 PM  6:00:00 PM