13

我总是在 sql server 中使用这个查询来获取表中的行号:

SELECT *
FROM   (SELECT *,
               Row_number()
                 OVER(
                   ORDER BY [myidentitycolumn]) RowID
        FROM   mytable) sub
WHERE  rowid = 15  

现在我在 Access 2010 中工作,这似乎不起作用。在 Access 中是否可以替换此查询?

4

7 回答 7

12

在查询中分配行号的另一种方法是使用该DCount函数。

SELECT *, DCount("[ID]","[mytable]","[ID]<=" & [ID]) AS row_id
FROM [mytable]
WHERE row_id=15
于 2013-06-25T16:54:41.560 回答
8

MS-Access 不支持 ROW_NUMBER()。使用前 1:

SELECT TOP 1 *
FROM [MyTable]
ORDER BY [MyIdentityCOlumn]

如果您需要第 15 行 - MS-Access 没有简单的内置方法来执行此操作。您可以通过使用反向嵌套排序来模拟行号来获得:

SELECT TOP 1 *
FROM (
  SELECT TOP 15 *
  FROM [MyTable]
  ORDER BY [MyIdentityColumn] ) t
ORDER BY [MyIdentityColumn] DESC
于 2013-06-24T15:36:41.517 回答
3

虽然这是一个老问题,但这对我有用,但我从未测试过它的效率......

SELECT 
    (SELECT COUNT(t1.SourceID) 
     FROM [SourceTable] t1 
     WHERE t1.SourceID<t2.SourceID) AS RowID, 
    t2.field2, 
    t2.field3, 
    t2.field4, 
    t2.field5
FROM 
    SourceTable AS t2
ORDER BY 
    t2.SourceID;

这种方法的一些优点:

  • 它也不依赖于表格的顺序——它RowID是根据它的实际值和小于它的值来计算的。
  • 此方法可以应用于任何(主键)类型(例如NumberStringDate)。
  • 这种方法与SQL完全无关,或者只需要很少的调整。

最后的想法

虽然这几乎适用于任何数据类型,但我必须强调,对于某些人来说,它可能会产生其他问题。例如,对于字符串,请考虑:

ID     Description    ROWID
aaa    Aardvark           1
bbb    Bear               2
ccc    Canary             3

如果我要插入:bba Boar,那么Canary RowID将改变......

ID     Description    ROWID
aaa    Aardvark           1
bbb    Bear               2
bba    Boar               3
ccc    Canary             4
于 2018-10-22T14:22:17.120 回答
1

我需要每支球队最好的x分结果。

当有相同点的结果时,排名并不能解决这个问题。所以我需要一个recordnumber

我在 Access 中创建了一个 VBA 函数来创建一个recordnumber在 ID 更改时重置的函数。

您必须查询此查询,了解从哪里recordnumber <= x获得每个团队的积分。

NB Access 更改记录号

  1. 当您查询按记录号过滤的查询时
  2. 当你过滤掉一些结果时
  3. 当您更改排序顺序时

那不是我认为会发生的事情。

通过使用临时表并在表中保存recordnumbersand 键或额外字段来解决此问题。

SELECT ID, Points, RecordNumberOffId([ID}) AS Recordnumber
FROM Team ORDER BY ID ASC, Points DESC;

它使用 3 个模块级变量来记住调用之间

Dim PreviousID As Long
Dim PreviousRecordNumber As Long
Dim TimeLastID As Date

Public Function RecordNumberOffID(ID As Long) As Long 
'ID is sortgroup identity
'Reset if last call longer dan nn seconds in the past
If Time() - TimeLastID > 0.0003 Then '0,000277778 = 1 second
    PreviousID = 0
    PreviousRecordNumber = 0
End If
If ID <> PreviousID Then
    PreviousRecordNumber = 0
    PreviousID = ID
End If
PreviousRecordNumber = PreviousRecordNumber + 1
RecordNumberOffID = PreviousRecordNumber
TimeLastID = Time()
End Function
于 2016-03-15T16:56:31.870 回答
0

由于我在字符串字段上按字母顺序排序而不是按 ID 排序,因此 Count(*) 和 DCOUNT() 方法对我不起作用。我的解决方案是编写一个返回行号的函数:

Option Compare Database
Option Explicit
Private Rst As Recordset

Public Function GetRowNum(ID As Long) As Long
  If Rst Is Nothing Then
    Set Rst = CurrentDb.OpenRecordset("SELECT ID FROM FileList ORDER BY RealName")
  End If
  Rst.FindFirst "ID=" & ID
  GetRowNum = Rst.AbsolutePosition + 1
' Release the Rst 1 sec after it's last use
'------------------------------------------
  SetTimer Application.hWndAccessApp, 1, 1000, AddressOf ReleaseRst  
End Function


Private Sub ReleaseRst(ByVal hWnd As LongPtr, ByVal uMsg As Long, ByVal nIDEEvent As Long, ByVal dwTime As Long)
  KillTimer Application.hWndAccessApp, 1 
  Set Rst = Nothing
End Sub
于 2019-06-28T14:48:51.343 回答
0

感谢您的上述解决方案!DCount 也为我做了诀窍!

我必须将日期列和唯一标识符组合用于它的排序部分(以及一些附加条件),所以这就是我最终要做的事情:1)我必须检查 DateColumnA 是否为空,然后检查如果 DateColumnB 为空,则使用 DateColumnC;那么,如果多条记录具有相同的日期值,它们都以相同的 id 结束!2)所以,我想我会使用表的整数唯一ID,并将它添加到时间作为“分钟”。这将始终提供不同的结果 3) 最后,上面的逻辑导致计数从 0 开始......所以只需加 1!

SELECT 
 1+DCount("[RequestID]","[Request]","Archived=0 and ProjectPhase <> 2 and iif(isnull(DateColumnA)=true,iif(isnull(DateColumnB)=true,DateColumnC,DateColumnB),DateColumnA)+(RequestID/3600) < #" & if(isnull(DateColumnA)=true,iif(isnull(DateColumnB)=true,DateColumnC,DateColumnB),DateColumnA) + (RequestID/3600) & "#") AS RowID, 
FROM 
 Request
ORDER BY 1

我希望这可以帮助你!

于 2019-12-03T22:48:49.840 回答
-1

我可能迟到了。只需在表格中添加一个新的字段 ID,类型为 AutoNumber。这将生成唯一的 ID,也可以在 Access 中使用

于 2015-10-27T20:55:10.983 回答