【问题标题】:Access SQL - Add Row Number to Query Result for a Multi-table JoinAccess SQL - 为多表连接的查询结果添加行号
【发布时间】:2026-02-23 21:00:02
【问题描述】:

我想做的很简单。 我只想在查询中添加行号。由于这在Access中比其他SQL要困难一些,但在一般情况下使用DCount或Select Count(*)等解决方案还是可行的,这里的例子:How to show row number in Access query like ROW_NUMBER in SQLAccess SQL how to make an increment in SELECT query

我的问题

我的问题是我正在尝试将此计数器添加到 按多个表中的字段排序的多连接查询

疑难解答

我的代码有点荒谬(19 个字段,其中 7 个是长表达式,来自 9 个不同的连接表,并按其中 5 个表的字段排序)。为简单起见,我在下面有一个简化的示例查询:

示例查询

SELECT DCount("*","Requests_T","[Requests_T].[RequestID]<=" & [Requests_T].[RequestID]) AS counter, Requests_T.RequestHardDeadline AS Deadline, Requests_T.RequestOverridePriority AS Priority, Requests_T.RequestUserGroup AS [User Group], Requests_T.RequestNbrUsers AS [Nbr of Users], Requests_T.RequestSubmissionDate AS [Submitted on], Requests_T.RequestID
FROM (((((((Requests_T 
    INNER JOIN ENUM_UserGroups_T ON ENUM_UserGroups_T.UserGroups = Requests_T.RequestUserGroup) 
    INNER JOIN ENUM_RequestNbrUsers_T ON ENUM_RequestNbrUsers_T.NbrUsers = Requests_T.RequestNbrUsers) 
    INNER JOIN ENUM_RequestPriority_T ON ENUM_RequestPriority_T.Priority = Requests_T.RequestOverridePriority) 
ORDER BY Requests_T.RequestHardDeadline, ENUM_RequestPriority_T.DisplayOrder DESC , ENUM_UserGroups_T.DisplayOrder, ENUM_RequestNbrUsers_T.DisplayOrder DESC , Requests_T.RequestSubmissionDate;

如果上面的代码试图从未包含的表中选择一个字段,我深表歉意 - 请相信该字段来自某个地方(大声笑,即我排除在简单查询中的其他联接之一)。一个很好的例子是ORDER BY 表达式中使用的.DisplayOrder 字段。这些是表中的字段,仅确定枚举的“优先级”。示例:Requests_T.RequestOverridePriority 向用户显示为“低”、“中”、“高”的组合框选项。所以在表格中,我分别为这些选项分配了数字优先级“1”、“2”和“3”。因此,当在order by 中调用ENUM_RequestPriority_T.DisplayOrder DESC 时,所有“高”优先级请求将显示在“中”和“低”之上。 ENUM_UserGroups_T.DisplayOrderENUM_RequestNbrUsers_T.DisplayOrder 也是如此。

出于效率考虑,我也不想使用 DCOUNT,而是执行以下操作:

select count(*) from Requests_T where Requests_T.RequestID>=RequestID) as counter

然而,由于“Order By”表达式,我的“计数器”实际上并没有按顺序计算结果行,因为我的两个示例都与 RequestID 相关联。

示例结果

根据我的实际查询结果,我制作了上面查询的示例结果。

Counter  Deadline   Priority  User_Group  Nbr_of_Users  Submitted_on  RequestID
5        12/01/2016 High      IT          2-4           01/01/2016    5
7        01/01/2017 Low       IT          2-4           05/06/2016    8
10                  Med       IT          2-4           07/13/2016    11
15                  Low       IT          10+           01/01/2016    16
8                   Low       IT          2-4           01/01/2016    9
2                   Low       IT          2-4           05/05/2016    2

查询以正确的顺序显示我的结果(最接近截止日期的在顶部,然后是具有最高优先级的那些,然后是用户组,然后是用户数,最后,如果其他所有条件都相同,则为按提交日期排序)。 但是,我的“计数器”值完全错误!计数器字段应该简单地为每个新行添加 +1。因此,如果在表单上为用户显示单个请求,我可以说

"您是号码:Counter [关联到 RequestID] 在 开发队列。”

同时我的结果:

  1. 不是顺序的(注意前四行是顺序显示的,但最后两行不是)!尽管最后两行的优先级低于它们上面的记录,但它们最终的 Counter 值较低,仅仅是因为它们具有较低的 RequestID
  2. 它们不是从“1”开始,而是为每条新记录增加 +1。

理想结果

因此,我从上面得到的理想结果是:

Counter  Deadline   Priority  User_Group  Nbr_of_Users  Submitted_on  RequestID
1        12/01/2016 High      IT          2-4           01/01/2016    5
2        01/01/2017 Low       IT          2-4           05/06/2016    8
3                   Med       IT          2-4           07/13/2016    11
4                   Low       IT          10+           01/01/2016    16
5                   Low       IT          2-4           01/01/2016    9
6                   Low       IT          2-4           05/05/2016    2

我被 PLSQL 和其他自动运行的软件宠坏了,哈哈。这真让我抓狂!任何帮助将不胜感激。

仅供参考 - 如果可能的话,我更喜欢 SQL 选项而不是 VBA。 VBA 非常受欢迎,如果它有效,肯定会得到支持,非常感谢,但我想将 SQL 选项标记为答案。

【问题讨论】:

  • 您的计数器将非常困难,因为它必须与您的 ORDER BY 子句中的每个字段相关联,并且这些字段来自连接。因此,您的 count 子查询必须有连接。更具挑战性的是 ASCDESC 之间的交换。
  • 或者,使用自动编号将查询记录附加到临时表,然后运行计数子查询(因为自动增量 ID 可能会因数据更改而跳过)。这样,您的关联只是一个没有连接的表,但交换仍然是一个问题。

标签: sql ms-access join row-number


【解决方案1】:

不幸的是,MS Access 没有像其他客户端那样非常有用的 ROW_NUMBER() 函数。所以我们只能即兴发挥。

由于您的查询非常复杂且 MS Access 不支持公用表表达式,我建议您遵循两步流程。首先,将您已经编写的查询命名为IntermediateQuery。然后,编写名为FinalQuery 的第二个查询,执行以下操作:

SELECT i1.field_primarykey, i1.field2, ... , i1.field_x,
    (SELECT field_primarykey FROM IntermediateQuery i2
     WHERE t2.field_primarykey <= t1.field_primarykey) AS Counter
FROM IntermediateQuery i1
ORDER BY Counter

不幸的副作用是您的表返回的数据越多,内联子查询的计算时间就越长。但是,这是获取行号的唯一方法。它确实取决于表中有一个主键。在这种特殊情况下,它不必是明确定义的主键,它只需要是对每条记录完全唯一的字段或字段组合即可。

【讨论】: