2011-05-19 112 views
3

假设我使用int Page,int Section和int ID标识字段创建一个表,其中页面字段的范围为1到8,部分字段的范围为1到30。现在让我们说,两个记录有重复的页面和部分。我怎么能重新编号这两个记录,以便页面和部分编号的顺序是连续的?简单SQL:如何计算集合中重复项的唯一连续数字?

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) 
+1

重复总是每页最高编号的部分?我们可以肯定,例如,数据集中没有(page = 1,section = 4)?如果重复的“部分”是30​​,我们是否需要增加“页面”? – pilcrow 2011-05-19 04:06:10

+0

+1,想知道是否有办法做到这一点没有光标,没有'ROW_NUMBER' – AakashM 2011-05-19 06:51:24

回答

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 
0

免责声明:我没有SQL服务器进行测试。

如果我理解正确的话,如果你知道你的#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 

这不会处理重复次数推动你超过你的上限30的情况。它也可能创建新的重复项,如果每个页面有更高编号的部分已经存在 - 也就是说,(pg 1, sec 3)的一个实例变成(pg 1, sec 4),这已经存在 - 但您可以重复运行UPDATE,直到不存在重复。

然后在(page, section)上添加一个唯一索引。