简单SQL:如何计算集合中重复项的唯一连续数字?

时间:2011-05-19 02:25:30

标签: sql tsql sql-server-2000

假设我创建了一个带有int Page,int Section和int ID identity字段的表,其中page字段的范围是1到8,每个页面的section字段的范围是1到30。现在让我们说两个记录有重复的页面和部分。我怎样才能重新编号这两个记录,以便页面和章节编号的顺序是连续的?

select page, section
from #fun
group by page, section having count(*) > 1

显示重复项:

page 1 section 3
page 2 section 3

第1页第4节和第2页第4节缺失。有没有办法不使用游标来查找和重新编号SQL 2000中不支持Row_Number()的位置?

下面的这个rownum当然会产生与章节中完全相同的数字:

select page, section,
    (select count(*) + 1 
     from #fun b 
     where b.page = a.page and b.section < a.section) as rownum
from #fun a

我可以创建一个数值为1到100的数据透视表,但我会加入什么?

我想做的是这样的事情:

update p set section = (expression that gets 4)
from #fun p
where (expression that identifies duplicate sections by page)

2 个答案:

答案 0 :(得分:1)

我没有2000服务器来测试它,但我认为它应该可以工作。

创建测试表/数据:

CREATE TABLE #fun
(Id INT IDENTITY(100,1)
,page INT NOT NULL
,section INT NOT NULL
)


INSERT #fun (page, section)
SELECT 1,1
UNION ALL SELECT 1,3    UNION ALL SELECT 1,2
UNION ALL SELECT 1,3    UNION ALL SELECT 1,5
UNION ALL SELECT 2,1    UNION ALL SELECT 2,2
UNION ALL SELECT 2,3    UNION ALL SELECT 2,5
UNION ALL SELECT 2,3

现在处理:

-- create a worktable
CREATE TABLE #fun2
(Id INT IDENTITY(1,1)
,funId INT
,page INT NOT NULL
,section INT NOT NULL
)

-- insert data into the second temp table ordered by the relevant columns
-- the identity column will form the basis of the revised section number
INSERT  #fun2 (funId, page, section)
SELECT  Id,page,section
FROM    #fun
ORDER BY page,section,Id

-- write the calculated section value back where it is different
UPDATE  p
SET     section = y.calc_section
FROM    #fun AS p 
JOIN
        (
            SELECT  f2.funId, f2.id - x.adjust calc_section
            FROM    #fun2 AS f2
            JOIN    (
                        -- this subquery is used to calculate an offset like
                        -- PARTITION BY in a 2005+ ROWNUMBER function
                        SELECT MIN(Id) - 1 adjust, page
                        FROM #fun2
                        GROUP BY page
                    ) AS x
            ON      f2.page = x.page
        ) AS y
ON      p.Id = y.funId
WHERE   p.section <> y.calc_section


SELECT * FROM #fun order by page, section

答案 1 :(得分:0)

免责声明:我没有要测试的SQL Server。

如果我理解正确,如果您知道#fun(page, section)个记录的ROW_NUMBER分区超过 UPDATE p SET section = section + (rownumber - 1) FROM #fun AS p INNER JOIN ( -- SELECT id, ROW_NUMBER() OVER (PARTITION BY page, section) ... SELECT id, COUNT(1) AS rownumber FROM #fun a LEFT JOIN #fun b ON a.page = b.page AND a.section = b.section AND a.id <= b.id GROUP BY a.id, a.page, a.section) d ON p.id = d.id WHERE rownumber > 1 个重复项,则可以使用此相对排名来增加“部分”:

(pg 1, sec 3)

这不会处理重复数量超过30的上限的情况。它也可能创建新的重复项,如果每页已存在更高编号的部分 - 这是,(pg 1, sec 4)的一个实例变为(page, section),已存在 - 但您可以反复运行UPDATE,直到不存在重复项。

然后在{{1}}上添加唯一索引。