【问题标题】:Row_Number() in Access select statementAccess 选择语句中的 Row_Number()
【发布时间】:2013-09-16 04:43:05
【问题描述】:

我相信有人问过类似的问题,但我找不到适合我的解决方案。

我有一个数据库,用于对数字化书籍及其页面进行排序,我正在尝试对包含地图的数千页进行排序。在我使用的两个表中,第一个列出了一本书中的所有页面以及它们在书中出现的顺序,它有三列(bookID、pageOrder、pageID),每一页都有自己的行。第二个表列出了每个页面上出现的所有地点(在地图中),如果一个页面上有多个地点,则它有两列(pageID,placeID),然后为每个地点在表中添加一个新行。

我需要做的是创建一个 select 语句,为每个 pageID/placeID 组合提供一个唯一编号,但这些编号必须按照它们在书中出现的顺序排列。在 SQL Server 中,我会这样做:

SELECT ROW_NUMBER() OVER(ORDER BY bp.bookID, bp.pageOrder, pp.placeID) AS uniqueNumber, pp.pageID, pp.placeID
FROM booksAndPages AS bp INNER JOIN pagesAndPlaces AS pp ON bp.pageID = pp.pageID

很遗憾,我无法使用 Access。理想情况下,我想(如果可能的话)使用单个 SQL 语句来完成,类似于上面的那个,但我也会尝试使用 VBA。

非常感谢任何帮助。

【问题讨论】:

标签: sql ms-access row-number


【解决方案1】:

这是您想要的查询:

SELECT ROW_NUMBER() OVER (ORDER BY bp.bookID, bp.pageOrder, pp.placeID) AS uniqueNumber,
       pp.pageID, pp.placeID
FROM booksAndPages AS bp INNER JOIN
     pagesAndPlaces AS pp
     ON bp.pageID = pp.pageID;

您可以使用相关子查询获得相同的结果。更复杂、更昂贵,但有可能:

SELECT (select count(*)
        from booksAndPages AS bp2 INNER JOIN
             pagesAndPlaces AS pp2
             ON bp2.pageID = pp2.pageID
        where bp2.bookID < bp.bookID or
              (bp2.bookID = bp.bookID and bp2.pageOrder < bp.pageOrder) or
              (bp2.bookID = bp.bookID and bp2.pageOrder = bp.pageOrder and
               bp2.placeId <= pp.PlaceId
              )
       ) as uniqueNumber,
       pp.pageID, pp.placeID
FROM booksAndPages AS bp INNER JOIN
     pagesAndPlaces AS pp
     ON bp.pageID = pp.pageID;

这假设 bookIdpageOrder、placeId 的组合是唯一的。

【讨论】:

    【解决方案2】:

    我知道这是一个老问题,但这是一个热门搜索,我没有在互联网上看到任何其他解决方案,所以我希望这对其他人有所帮助。

    我的解决方案适用于任何数据集,无论它是否具有唯一标识符。

    将以下 VBA 代码添加到模块中:

    Public row as Variant
    
    Function RowNum(dummy) As Integer
        row = row + 1
        RowNum = row
    End Function
    
    Function GetRowNum(dummy) As Integer
        GetRowNum = row
    End Function
    
    Function ResetRowNum()
        row = 0
    End Function
    

    下面是一个示例查询:

    SELECT Table1.Field1, Table1.Field2, RowNum([Field1]) AS RowId, 
        "Row: "&GetRowNum([Field1]) AS RowText
    FROM Table1
    

    如果您愿意,您可以添加任何“ORDER BY”甚至“GROUP BY”。您可以将查询输出中的任何字段用作RowNumGetRowNum 的输入。需要注意的重要一点是,仅在第一次需要行号时使用RowNum,之后每次都使用GetRowNum。这是为了防止一行多次增加计数器。

    您需要做的最后一件事是创建一个运行 ResetRowNum 的宏,并在您使用此方法的每个查询之后运行它,或者如果您通过宏或 VBA 运行一系列查询,请确保在使用这些函数的每个查询之后运行ResetRowNum

    同时避免查看数据表,因为它似乎在您滚动时不断重新计算公式,从而使数字稳步增加。

    【讨论】:

    • 您的RowNum 函数可以采用第二个可选的布尔参数,用于何时不应推进行。这样就不需要GetRowNum 函数了。
    【解决方案3】:

    查询排序和/或分组

    SELECT Table1.Field1, 
           Table1.SomeDate, 
           Table1.Field2,
           RowNumber([Field1]) AS RowId,
           "Row: " & GetRowNum([Field1]) AS RowText
    FROM Table1
    ORDER BY Table1.Field1, Table1.SomeDate;
    

    Field1  Field2  RowId   RowText
    James   2   1   Row: 1
    James   35  2   Row: 2
    James   6   3   Row: 3
    James   86  4   Row: 4
    James   67  5   Row: 5
    James   35  6   Row: 6
    Maria   4   1   Row: 1
    Maria   54  2   Row: 2
    Samuel  46  1   Row: 1
    Samuel  32  2   Row: 2
    Samuel  7   3   Row: 3
    Thomas  43  1   Row: 1
    Thomas  65  2   Row: 2
    Thomas  5   3   Row: 3
    

    Public StoredRowNumber As Variant
    Public OldlastField As Variant
    
    Function RowNumber(TheField) As Integer
        If OldlastField = TheField Then
            'nada
        Else
            ResetRowNum
        End If
        StoredRowNumber = StoredRowNumber + 1
        RowNumber = StoredRowNumber
        OldlastField = TheField
    End Function
    
    Function GetRowNum(TheField) As Integer
        GetRowNum = StoredRowNumber
    End Function
    
    Function ResetRowNum()
        StoredRowNumber = 0
        'OldFieldItem = Null
    End Function
    

    【讨论】:

    • 查询排序或分组:
    • 当我滚动并单击结果时,函数返回的值似乎会更新。此外,如果我在函数列 WHERE RowID = 1 上添加 WHERE 子句,我也会得到显示 RowID =2 的结果
    • 非常正确。我将它用于访问报告过程。一种 VBA 存储过程,我需要大型数据集中的第三项。如果您将其用作屏幕表单,您可能希望将其作为临时表拉入,或者使用唯一的记录标识符,如果您需要返回实时制作表并进行更新。但那是一个非常不同的故事,记录锁定和整个 9 码。也许9.7码。这是特别需要的: 报告流程;非常大的数据集;一个特定的row_number;不需要视图。即Access中的SQL服务器ROW_NUMBER
    • Still is只是一个开始,考虑到它是VBA,功能扩展的极限是天空。问题是,我搜索了多个站点都无济于事,所以我不得不花时间来构建它,我不时将它提供给下一个人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-09
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 2011-02-14
    • 1970-01-01
    相关资源
    最近更新 更多