简体   繁体   English

SQL 服务器:枚举使用 ROW_NUMBER() OVER (PARTITION

[英]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).如您所见,我正在按 MARKET 分组并且需要枚举组(然后我将使用此枚举来分页并显示起始页和分隔符之间的 N 个组)。

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.我选择最后一个索引(第一个 select 和 TOP 1),因为 DENSE_RANK() 以相反的顺序返回组计数器。

I'm sure this can be done with only one query, but not sure how.我确信这可以只用一个查询来完成,但不确定如何。

Any help?有什么帮助吗?

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:我的最后一个查询是枚举 MARKET 组的位置:

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.在我的帖子中,由于内部“ORDER BY MARKET DESC”中的“desc”,我没有意识到以相反顺序显示的行,删除该 desc,DENSE_RANK() 显示 seqnum1(我的组计数器列的名称)以正确的顺序,然后我可以避免第一个 select 得到最后一个索引,所以我最终得到一个 select 枚举市场组,因此,我将能够按市场组分页。

I cannot say it's the best way to do it, but it's working.我不能说这是最好的方法,但它确实有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM