访问 SQL/Logic 以根据复合键递增 Key/Field
Access SQL/Logic for Incrementing Key/Field based on composite key
假设您在数据库中有一个 table 每天跟踪 9 个办公地点的工单出现次数 4 到 5 次。在每个时间段内,人们可能会出现一张票(我想我们可以使用交易模型),或者他们会出现很多张票(我见过一些人有 15 张,听说其他人有多达 50 张)。
使用 Access 2013 创建了一个查询,以从此 table 捕获数据。这样做是为了存档(当前日期 table 记录在 24 小时后被清除)和一般分析。
当前查询逻辑如下:
SELECT Format([T1]![APP_DTE],"Short Date") AS APPEAR_DTE,
T1.OFFICE, OFFCDES.OFFICE_NAME, OFFCDES.LOC_CDE, OFFCDES.LOC_NAME,
T1.APP_TIME_PER, T1.ROOM_NUM, T1.INCL_CDE, T1.ID_NUMB,
T1.ADJ_APPEAR_NUM, T2.APPEAR_CDE,
IIf([T1]![APPEAR_LOGIN_TIME] Is Null,"",[T1]![APPEAR_LOGIN_TIME]) AS LOGIN_TIME1,
IIf([T1]![OFFICE_LOGIN] Is Null,"",[T1]![OFFICE_LOGIN]) AS OFFICE_LOGIN,
IIf([T1]![DECISION_TIME] Is Null,"",[T1]![DECISION_TIME]) AS DECISION_TIME,
[T1]![ID_NUMB] & "-" & CStr([T2]![OFFICE_REP_ID]) & "-" & CStr([T1]![APP_DTE]) AS CASEKEY,
Weekday([APP_DTE]) AS NUM_DAY,
[T1]![OFFICE] & "-" & Weekday([T1]![APP_DTE]) & "-" & [T1]![APP_TIME_PER] AS OFFICE_TP_KEY, "" AS RecordKey
FROM (T1 INNER JOIN OFFCDES ON T1.OFFICE = OFFCDES.OFFICE)
INNER JOIN T2 ON T1.APPEAR_NUM = T2.APPEAR_NUM
WHERE (((Format([T1]![APP_DTE],"Short Date"))=Format(Date(),"Short Date")));
我意识到上面的代码需要清理以提高可读性,并且它可能没有它应该的那样高效。那部分我不能相信,我从同事那里继承了所有这些,并且刚刚开始全神贯注。
查询结果包含大量信息,其中一些(大部分)信息与我要完成的任务无关。捕获所有这些信息很重要,因为信息一旦消失就消失了。话虽如此:
我想做什么:
我正在尝试合并一个 key/sequentially 编号列,它会告诉我特定 ID_NUMB 在提取日期的特定 Office/Time 期间发生了多少次。我也不是在寻找总数,而是在此处的 SEQ 列中查找:
ID_NUMB | APPEAR_NUM | OFFICE | TP | DATE | SEQ
1 | 1XZ2 | 01 | 01 | 9/7/2016 | 1
1 | 1XZ3 | 01 | 01 | 9/7/2016 | 2
2 | 3MN1 | 03 | 01 | 9/7/2016 | 1
3 | J915 | 02 | 01 | 9/7/2016 | 1
1 | 1TY1 | 01 | 01 | 9/7/2016 | 1
3 | P91D | 05 | 01 | 9/7/2016 | 1
2 | U11E | 11 | 05 | 9/7/2016 | 1
虽然我环顾四周并发现了许多很好的编号解决方案,但大多数都不是我想要完成的,因为计数的粒度似乎太细了。
我考虑过将数据写入临时文件 table,但使用我发现的一些信息并没有找到任何解决方案。相似地,
我尝试编写一个单独的查询来检索此信息并添加序列号,这是对 MS Answers 网站上发现的 the solution 的一种改编。我把它放在一边,因为它似乎是错误的方法。
我什至尝试将查询写入临时 table,然后让 VBA 处理顺序编号,但这种方法也没有走得太远。
如我所述,在列中生成序号的正确方法是什么?我不知所措。
对于此类任务,最直接的方法通常是使用 DAO 打开一个 recordset,其中记录的顺序如下到你需要的顺序。
然后遍历记录集,为每条记录跟踪将强制使用新序列号或仅将前一个序列号加一的条件。现在,构建序列号,更新记录,然后继续,直到没有更多记录。
编辑:循环记录示例:
Dim rst As DAO.Recordset
'Me.RecordsetClone
Set rst = Me.RecordsetClone
rst.Sort = "Dato, ID asc"
Set rst = rst.OpenRecordset()
rst.MoveFirst
While rst.EOF = False
Debug.Print rst!Dato.Value, rst!Id.Value
' If SomeCondition = True Then
rst.Edit
rst!Dec1.Value = rst!Id.Value
rst.Update
' End If
rst.MoveNext
Wend
我认为这个 SQL 可能接近您想要的(基于有限的示例)它在 table T1 上执行 INNER JOIN - 并在构建之前执行简单排序实时 SEQ
SELECT
a.ID_NUMB,
a.ADJ_APPEAR_NUM,
a.OFFICE,
a.APP_TIME_PER AS TP,
Format(a.[APP_DTE],"Short Date") AS APP_DATE,
(SELECT Count(ID_NUMB)
FROM T1 b
WHERE (b.ADJ_APPEAR_NUM <= a.ADJ_APPEAR_NUM
AND b.ID_NUMB = a.ID_NUMB
AND b.OFFICE = a.OFFICE
AND b.APP_TIME_PER = a.APP_TIME_PER
AND b.APP_DTE = a.APP_DTE)) AS SEQ
FROM T1 AS a
ORDER BY a.ID_NUMB, a.OFFICE, a.ADJ_APPEAR_NUM;
查询结果(使用您的 T1 数据)
假设您在数据库中有一个 table 每天跟踪 9 个办公地点的工单出现次数 4 到 5 次。在每个时间段内,人们可能会出现一张票(我想我们可以使用交易模型),或者他们会出现很多张票(我见过一些人有 15 张,听说其他人有多达 50 张)。
使用 Access 2013 创建了一个查询,以从此 table 捕获数据。这样做是为了存档(当前日期 table 记录在 24 小时后被清除)和一般分析。
当前查询逻辑如下:
SELECT Format([T1]![APP_DTE],"Short Date") AS APPEAR_DTE,
T1.OFFICE, OFFCDES.OFFICE_NAME, OFFCDES.LOC_CDE, OFFCDES.LOC_NAME,
T1.APP_TIME_PER, T1.ROOM_NUM, T1.INCL_CDE, T1.ID_NUMB,
T1.ADJ_APPEAR_NUM, T2.APPEAR_CDE,
IIf([T1]![APPEAR_LOGIN_TIME] Is Null,"",[T1]![APPEAR_LOGIN_TIME]) AS LOGIN_TIME1,
IIf([T1]![OFFICE_LOGIN] Is Null,"",[T1]![OFFICE_LOGIN]) AS OFFICE_LOGIN,
IIf([T1]![DECISION_TIME] Is Null,"",[T1]![DECISION_TIME]) AS DECISION_TIME,
[T1]![ID_NUMB] & "-" & CStr([T2]![OFFICE_REP_ID]) & "-" & CStr([T1]![APP_DTE]) AS CASEKEY,
Weekday([APP_DTE]) AS NUM_DAY,
[T1]![OFFICE] & "-" & Weekday([T1]![APP_DTE]) & "-" & [T1]![APP_TIME_PER] AS OFFICE_TP_KEY, "" AS RecordKey
FROM (T1 INNER JOIN OFFCDES ON T1.OFFICE = OFFCDES.OFFICE)
INNER JOIN T2 ON T1.APPEAR_NUM = T2.APPEAR_NUM
WHERE (((Format([T1]![APP_DTE],"Short Date"))=Format(Date(),"Short Date")));
我意识到上面的代码需要清理以提高可读性,并且它可能没有它应该的那样高效。那部分我不能相信,我从同事那里继承了所有这些,并且刚刚开始全神贯注。
查询结果包含大量信息,其中一些(大部分)信息与我要完成的任务无关。捕获所有这些信息很重要,因为信息一旦消失就消失了。话虽如此:
我想做什么:
我正在尝试合并一个 key/sequentially 编号列,它会告诉我特定 ID_NUMB 在提取日期的特定 Office/Time 期间发生了多少次。我也不是在寻找总数,而是在此处的 SEQ 列中查找:
ID_NUMB | APPEAR_NUM | OFFICE | TP | DATE | SEQ
1 | 1XZ2 | 01 | 01 | 9/7/2016 | 1
1 | 1XZ3 | 01 | 01 | 9/7/2016 | 2
2 | 3MN1 | 03 | 01 | 9/7/2016 | 1
3 | J915 | 02 | 01 | 9/7/2016 | 1
1 | 1TY1 | 01 | 01 | 9/7/2016 | 1
3 | P91D | 05 | 01 | 9/7/2016 | 1
2 | U11E | 11 | 05 | 9/7/2016 | 1
虽然我环顾四周并发现了许多很好的编号解决方案,但大多数都不是我想要完成的,因为计数的粒度似乎太细了。
我考虑过将数据写入临时文件 table,但使用我发现的一些信息并没有找到任何解决方案。相似地, 我尝试编写一个单独的查询来检索此信息并添加序列号,这是对 MS Answers 网站上发现的 the solution 的一种改编。我把它放在一边,因为它似乎是错误的方法。
我什至尝试将查询写入临时 table,然后让 VBA 处理顺序编号,但这种方法也没有走得太远。
如我所述,在列中生成序号的正确方法是什么?我不知所措。
对于此类任务,最直接的方法通常是使用 DAO 打开一个 recordset,其中记录的顺序如下到你需要的顺序。
然后遍历记录集,为每条记录跟踪将强制使用新序列号或仅将前一个序列号加一的条件。现在,构建序列号,更新记录,然后继续,直到没有更多记录。
编辑:循环记录示例:
Dim rst As DAO.Recordset
'Me.RecordsetClone
Set rst = Me.RecordsetClone
rst.Sort = "Dato, ID asc"
Set rst = rst.OpenRecordset()
rst.MoveFirst
While rst.EOF = False
Debug.Print rst!Dato.Value, rst!Id.Value
' If SomeCondition = True Then
rst.Edit
rst!Dec1.Value = rst!Id.Value
rst.Update
' End If
rst.MoveNext
Wend
我认为这个 SQL 可能接近您想要的(基于有限的示例)它在 table T1 上执行 INNER JOIN - 并在构建之前执行简单排序实时 SEQ
SELECT
a.ID_NUMB,
a.ADJ_APPEAR_NUM,
a.OFFICE,
a.APP_TIME_PER AS TP,
Format(a.[APP_DTE],"Short Date") AS APP_DATE,
(SELECT Count(ID_NUMB)
FROM T1 b
WHERE (b.ADJ_APPEAR_NUM <= a.ADJ_APPEAR_NUM
AND b.ID_NUMB = a.ID_NUMB
AND b.OFFICE = a.OFFICE
AND b.APP_TIME_PER = a.APP_TIME_PER
AND b.APP_DTE = a.APP_DTE)) AS SEQ
FROM T1 AS a
ORDER BY a.ID_NUMB, a.OFFICE, a.ADJ_APPEAR_NUM;
查询结果(使用您的 T1 数据)