Row_Number() in Access select statement

user2770656 picture user2770656 · Sep 12, 2013 · Viewed 45.6k times · Source

I believe similar questions have been asked but I can't quite find a solution that works for me.

I've got a database that I use to sort through digitised books and their pages and I'm trying to sort through several thousand pages that contain maps. Of the two tables I'm using the first lists all the pages in a book and the order they occur in the book, it's got three columns (bookID, pageOrder, pageID), each page has its own row. The second table lists all the places (in a map) that occur on each page, it has two columns (pageID, placeID) if there are multiple places on one page then a new row is added to the table for each place.

What I need to do is create a select statement that gives every pageID/placeID combination a unique number but the numbers must go in the order they appear in the book. In SQL Server I would do this:

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

Unfortunately, I'm stuck using Access. Ideally I'd like to do it (if possible) with a single SQL statement, similar to the one above but I would also try it using VBA.

Any help is greatly appreciated.

Answer

Gordon Linoff picture Gordon Linoff · Sep 12, 2013

This is the query that you want:

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;

You can get the same result using a correlated subquery. More complicated and more expensive, but possible:

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;

This assumes that the combination bookId, pageOrder, placeId` is unique.