交叉表查询空白处

CrossTab Query empty places

我有一个 table,其中指定了 ID、长度、工作时间、日期

我需要创建一个交叉表查询,其中将在工作长度内的每一天写入当天完成的工作时间数。如果有一个空白 space 我需要在那里有数字零。然而,在工作的长度之后,我需要在那里有空白 space。

这是我的解决方案:

TRANSFORM Nz(Sum([SampleTable]![WorkHours]))+0 AS [Sum]
SELECT SampleTable.ID, SampleTable.Length
FROM SampleTable
WHERE (((SampleTable.Day)>0 And (SampleTable.Day)<200))
GROUP BY SampleTable.ID, SampleTable.Length
ORDER BY SampleTable.ID, SampleTable.Length
PIVOT SampleTable.Day;

我需要在检查长度后去掉零,取而代之的是空值。我的解决方案是在各处创建零,而不是仅在开始到长度之间的间隔中创建零。

当我尝试这个解决方案时,它仍然没有任何好处。在错误的地方只有几个空白 space。

TRANSFORM IIf([sampleTable].[length]>[sampleTable].[day],Null,Nz(Sum([SampleTable]![WorkHours]))+0) AS [Sum]
SELECT SampleTable.ID, SampleTable.Length
FROM SampleTable
WHERE (((SampleTable.Day)>0 And (SampleTable.Day)<200))
GROUP BY SampleTable.ID, SampleTable.Length
ORDER BY SampleTable.ID, SampleTable.Length
PIVOT SampleTable.Day;

本质上,您面临着差距和孤岛问题,您需要用零工作时间填补缺失的差距和不连续的孤岛,并有条件地使 ID 的值无效。对于您的细微需求,请考虑以下基本步骤。

  1. 创建所有可能的 IDDayLength 的交叉连接 table(使用 INTO 子句) WorkHours 填零:

    SELECT i.ID, d.Day, i.Length, 0 AS WorkHours
    INTO myCrossJoinTable
    FROM
      (SELECT DISTINCT [ID], [Length] FROM LengthWorkHoursDay) i,
      (SELECT DISTINCT [Day] FROM LengthWorkHoursDay) d
    WHERE d.Day IS NOT NULL
    

    要填写最多 100 天(或 table 中的最大值 Length),请使用 VBA 构建连续天数:

    Sub AppendData()
       Dim i As Long, sql As String
    
       CurrentDb.Execute "DELETE FROM SampleTable"
    
       For i = 1 to DMax("[Length]", "SampleTable")
           sql = "INSERT INTO myCrossJoinTable ([ID], [Day], [Length], [WorkHours]) " _
                  & "SELECT DISTINCT [ID], " & i & ", [Length], 0 " _
                  & "FROM SampleTable"
    
           CurrentDb.Execute sql
       Next i
    End Sub
    
  2. 创建一个单独的查询以将原始 table 与交叉联接 table 联接起来,以填补工作时间为零的顺序数据中的空白和不连续性。

    SELECT d.ID
           , d.Day
           , t.Day
           , d.Length
           , IIF(t.WorkHours IS NULL, d.WorkHours, t.WorkHours) AS WHours
    FROM myCrossJoinTable As d
    LEFT JOIN SampleTable AS t
       ON t.ID = d.ID 
       AND t.Day = d.Day
    WHERE (d.Day > 0 And d.Day < 200)
    
  3. 运行 基于上述基本查询的最终交叉表查询,条件 SUM 使值无效:

    TRANSFORM SUM(IIF(q.Day > q.Length, NULL, q.WHours)) AS [Sum]
    SELECT q.ID, q.Length
    FROM mySavedQuery q
    GROUP BY q.ID, q.Length 
    ORDER BY q.ID, q.Length
    PIVOT q.Day
    
    ID Length 1 2 3 4 5 6 7 8 9 10 11 12 13 14 100
    1 4 10 5 0 137
    2 6 25 0 0 0 67 0
    3 10 6 0 0 0 0 0 0 4 0 0
    4 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
    5 10 2 1 2 1 2 1 2 1 2 1