'SQL Server: Enumerating table query groups created with ROW_NUMBER() OVER (PARTITION

I have a query like the next:

DECLARE @RETURN_TABLE TABLE(
        MARKET varchar(200),
        NAMES varchar(200),
        PK_IDS VARCHAR (25),
        PFK_MARKET INT,
        IS_ADHOC BIT,
        FK_APPLICATION INT)

...

SELECT *
FROM (
    SELECT *, 
    ROW_NUMBER() OVER (PARTITION BY PK_IDS, MARKET ORDER BY is_adhoc desc) seqnum
    FROM @RETURN_TABLE 
) t
WHERE seqnum = 1 AND MARKET LIKE '%' + @MARKET + '%' 
ORDER BY MARKET

Which -as an example- returns something like this (with many more rows):

MARKET                      NAMES                       PK_IDS      PFK_MARKET  IS_ADHOC    FK_APP  seqnum
AB/West Region              AB - Value Add ...          1/2/39      226         1           0       1
AB/West Region              AB - Other Retail ...       1/3/39      226         1           0       1
AB/West Region - Breakthru  Browns Social ...           1/122/39    281         0           0       1
AB/West Region - Breakthru  Local STREET ...            1/123/39    281         0           0       1
AB/West Region - Breakthru  Moxie's STREET ...          1/124/39    281         0           0       1
adm Promotions              Branding Your POS ...       107/107/39  231         1           NULL    1
adm Promotions              Imagen Publicitaria ...     111/111/39  231         1           NULL    1
adm Promotions              ADM Promotions UK Limited   75/75/39    231         1           NULL    1

And I need to enumerate partitioned records (MARKET groups) so my result will look like the next:

MARKET                      NAMES                       PK_IDS      PFK_MARKET  IS_ADHOC    FK_APP  seqnum  seqnum1
AB/West Region              AB - Value Add ...          1/2/39      226         1           0       1       1
AB/West Region              AB - Other Retail ...       1/3/39      226         1           0       1       1
AB/West Region - Breakthru  Browns Social ...           1/122/39    281         0           0       1       2
AB/West Region - Breakthru  Local STREET ...            1/123/39    281         0           0       1       2
AB/West Region - Breakthru  Moxie's STREET ...          1/124/39    281         0           0       1       2
adm Promotions              Branding Your POS ...       107/107/39  231         1           NULL    1       3
adm Promotions              Imagen Publicitaria ...     111/111/39  231         1           NULL    1       3
adm Promotions              ADM Promotions UK Limited   75/75/39    231         1           NULL    1       3

As you see, I'm grouping by MARKET and need to enumerate groups (I will use then this enumeration to paginate and show N number of groups between a start page and delimiter).

I achieved something that is working, but I'm sure it can be done in a better way:

DECLARE @lastindex int

SET @lastindex = (SELECT TOP 1 seqnum1 
        FROM (
            SELECT *, 
            ROW_NUMBER() OVER (PARTITION BY PK_IDS, MARKET ORDER BY is_adhoc desc) seqnum,
            DENSE_RANK() OVER (ORDER BY MARKET desc) seqnum1 
            FROM @RETURN_TABLE 
        ) t
        WHERE seqnum = 1 AND MARKET LIKE '%' + @MARKET + '%' ORDER BY seqnum1 desc)

--

SELECT *
    FROM (
        SELECT *, 
        ROW_NUMBER() OVER (PARTITION BY PK_IDS, MARKET ORDER BY is_adhoc desc) seqnum,
        DENSE_RANK() OVER (ORDER BY MARKET desc) seqnum1 
        FROM @RETURN_TABLE 
    ) t
    WHERE seqnum = 1 AND MARKET LIKE '%' + @MARKET + '%'
    AND @lastindex BETWEEN @lastindex-((@LIMIT*@PAGE)-1) AND (@lastindex-((@LIMIT*@PAGE)-1))+(@LIMIT-1)
    ORDER BY seqnum1 desc

I'm selecting last index (first select with TOP 1) because DENSE_RANK() is returning the groups counter in reverse order.

I'm sure this can be done with only one query, but not sure how.

Any help?



Solution 1:[1]

Ok, for the moment I'll answer my own question in case it helps anyone else.

My final query, where the MARKET groups are enumerated is the next:

SELECT *
    FROM (
        SELECT *, 
        ROW_NUMBER() OVER (PARTITION BY PK_IDS, MARKET ORDER BY is_adhoc desc) seqnum,
        DENSE_RANK() OVER (ORDER BY MARKET) seqnum1 
        FROM @RETURN_TABLE 
    ) t
    WHERE seqnum = 1 AND MARKET LIKE '%' + @MARKET + '%'
    AND seqnum1 BETWEEN (@LIMIT*(@PAGE-1))+1 AND (@LIMIT*(@PAGE-1)) + @LIMIT
    ORDER BY seqnum1

In my post, I didn't realize rows where showing in reverse order because of the "desc" in the INNER "ORDER BY MARKET DESC", removing that desc, the DENSE_RANK() shows seqnum1 (the name of my groups counter column) in the correct order and then I can avoid the first select to get the last index, and so I finally get one select with the MARKET groups enumerated and so, I'll be able to paginate by groups of MARKETS.

I cannot say it's the best way to do it, but it's working.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Diego Perez