简体   繁体   中英

Incrementing Row_Number based on change in value of a column

I have a sql view which contains data from 3 linked entities (Title > Edition > SKU). The data in this view is used to search on ANY field within the 3 entities. For example, if you specify a condition title.regionid = '14' the view returns 4,000 unique rows (1 per SKU), which belong to 765 unique Editions, which belong to 456 unique Titles.

What I need is to enable paging based on Titles using Row_Number(). So

SELECT * FROM myview WHERE title.regionid = '14' AND Row BETWEEN 0 AND 35

The problem is that my Row column needs to count the rows by Title, not by SKU, so from a result set of 4,000 rows, if the first title contains 12 editions and 65 SKUs, the row number for all 65 rows should be 1, because they belong to the same Title.

I cannot use GroupBy because my view contains 40+ columns all of which can be searched on via the WHERE clause.

Here's the query:

SELECT *
FROM (
SELECT row_number() OVER (ORDER BY a.TitleSort ASC) AS Row, a.* 
FROM (SELECT * FROM v_AdvancedSearch 
WHERE 
    istitledeleted = 0
    --AND ISBN = '1-4157-5842-5'
    --AND etc
    ) AS a
) d
WHERE 
Row BETWEEN 0 AND 35

In the first page there are 35 rows which only belong to 4 titles, but the Row column counts by row so it stops there, whereas if it counted by Title I would get 387 rows for page 1... How can I accomplish paging in this situation?

WITH Titles AS
(
SELECT *
FROM (
SELECT row_number() OVER (ORDER BY a.TitleSort ASC) AS Row, a.* 
    FROM (SELECT DISTINCT TitleSORT, TitleId FROM v_AdvancedSearch 
    WHERE 
        istitledeleted = 0 
        --AND ISBN = '1-4157-5842-5'
        --AND PictureFormat = 'Widescreen'
        --AND UPC = '0-9736-14381-6-0'
        --AND Edition = 'Standard'
        ) AS a
) d
WHERE 
Row BETWEEN 0 AND 35
)
SELECT * FROM v_AdvancedSearch V
INNER JOIN Titles ON Titles.TitleId = V.TitleId 
WHERE istitledeleted = 0 
--CONDITIONS NEED TO BE REPEATED HERE
--AND ISBN = '1-4157-5842-5'
ORDER BY V.TitleSort ASC

This form works best for me

WITH 
[cte] AS ( 
    SELECT 
        DENSE_RANK ( ) OVER ( ORDER BY [v].[TitleSort], [v].[TitleId] ) AS [ordinal], 
        [v].[TitleSort], 
        [v].[TitleId] 
        --, 
        --field list, 
        --etc 
    FROM [v_AdvancedSearch] AS [v] 
    WHERE 
        [v].[istitledeleted] = 0 
        --AND 
        --additional conditions AND 
        --etc 
) 
SELECT 
    [v].[ordinal], 
    [v].[TitleSort], 
    [v].[TitleId] 
    --, 
    --field list, 
    --etc 
FROM [cte] AS [v] 
WHERE 
    [v].[ordinal] >= 0 AND 
    [v].[ordinal] <= 35 
ORDER BY [v].[ordinal]; 
  • No need for DISTINCT or GROUP BY
  • No need to repeat the criteria conditions
  • Just gotta have that explicit field list

https://docs.microsoft.com/en-us/sql/t-sql/functions/dense-rank-transact-sql

https://www.google.com/search?q=%22sql+server%22+%22select+star%22

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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