基于ADODB的Access SQL分组拼接_ORIG_ID实现撤销记录关联查询
问题
我正在使用Excel的ADODB组件从Access数据库的ANALYSES_UNDO撤销表中提取撤销条目列表。用户将通过_MODIFIED_BY和_MODIFIED_TIME的唯一组合选择某条“撤销项”,并需要检索其关联的所有记录,便捷方式是通过ID列表实现。
我希望编写第一个查询,按_MODIFIED_BY和_MODIFIED_TIME分组,将关联的_ORIG_ID拼接为逗号分隔的列表(命名为_REL_IDS),示例SQL语句如下:
SELECT Count(*), [_MODIFIED_BY], [_MODIFIED_TIME], CONCAT([_ORIG_ID],',') AS _REL_IDS FROM ANALYSES_UNDO GROUP BY [_MODIFIED_BY], [_MODIFIED_TIME] ORDER BY [_MODIFIED_TIME] DESC
用户选择该查询的某条记录后,将用_REL_IDS替换XXX,执行以下查询从ANALYSES表获取对应记录:
SELECT * FROM ANALYSES WHERE ID IN(XXX)
请问能否构建这样的查询?Access SQL是否支持此类字段拼接?我知道没有此类功能的CONCAT函数,仅用于演示需求。
解决方案
Access SQL本身不支持直接在GROUP BY查询中实现字段拼接为逗号分隔列表,但可以通过两种可行方式实现你的需求:
方法1:在Access中创建自定义VBA聚合函数
你可以在目标Access数据库中添加一个自定义VBA聚合函数,实现分组拼接字符串的功能:
- 打开Access数据库,按下
Alt+F11打开VBA编辑器 - 插入新模块,粘贴以下代码:
Function ConcatIDs(strID As Variant, strSeparator As String, ByRef strPrevID As String) As String If IsNull(strID) Then ConcatIDs = strPrevID Exit Function End If If strPrevID = "" Then strPrevID = strID Else strPrevID = strPrevID & strSeparator & strID End If ConcatIDs = strPrevID End Function
- 之后修改你的第一个查询,调用自定义函数完成拼接:
SELECT Count(*) AS RecordCount, [_MODIFIED_BY], [_MODIFIED_TIME], ConcatIDs([_ORIG_ID], ",", "") AS _REL_IDS FROM ANALYSES_UNDO GROUP BY [_MODIFIED_BY], [_MODIFIED_TIME] ORDER BY [_MODIFIED_TIME] DESC;
方法2:在Excel VBA中完成拼接逻辑
如果无法修改Access数据库添加VBA函数,可以拆分步骤在Excel端处理:
- 先执行基础分组查询,获取所有唯一的
_MODIFIED_BY和_MODIFIED_TIME组合:
SELECT Count(*) AS RecordCount, [_MODIFIED_BY], [_MODIFIED_TIME] FROM ANALYSES_UNDO GROUP BY [_MODIFIED_BY], [_MODIFIED_TIME] ORDER BY [_MODIFIED_TIME] DESC;
- 用户选中某条记录后,根据对应的
_MODIFIED_BY和_MODIFIED_TIME查询所有关联的_ORIG_ID:
SELECT [_ORIG_ID] FROM ANALYSES_UNDO WHERE [_MODIFIED_BY] = ? AND [_MODIFIED_TIME] = ?;
- 在Excel VBA中遍历查询结果,将
_ORIG_ID拼接为逗号分隔的字符串,再代入第二个查询:
SELECT * FROM ANALYSES WHERE ID IN(/* 拼接好的ID字符串 */);
注意事项
- 方法1需要确保Access数据库允许运行VBA代码,且ADODB连接能正常调用自定义函数
- 方法2中如果
_ORIG_ID数量过多,IN子句可能超出Access SQL的参数限制,此时可考虑使用临时表优化查询逻辑
内容的提问来源于stack exchange,提问作者j74nilsson
相关产品推荐
相关产品推荐

