2011-05-19 109 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)上添加一個唯一索引。