2014-08-29 75 views
0

我有一組表格(有幾個一對多關係),形成一個單元。我需要確保我們清除重複項,但確定重複項需要考慮所有數據。確定重複的Xml節點

更糟的是,有問題的數據庫仍然處於Sql 2000兼容模式,所以它不能使用任何更新的功能。

Create Table UnitType 
(
    Id int IDENTITY Primary Key, 
    Action int not null, 
    TriggerType varchar(25) not null 
) 

Create Table Unit 
(
    Id int IDENTITY Primary Key, 
    TypeId int Not Null, 
    Message varchar(100), 
    Constraint FK_Unit_Type Foreign Key (TypeId) References UnitType(Id) 
) 

Create Table Item 
(
    Id int IDENTITY Primary Key, 
    QuestionId int not null, 
    Sequence int not null 
) 

Create Table UnitCondition 
(
    Id int IDENTITY Primary Key, 
    UnitId int not null, 
    Value varchar(10), 
    ItemId int not null 
    Constraint FK_UnitCondition_Unit Foreign Key (UnitId) References Unit(Id), 
    Constraint FK_UnitCondition_Item Foreign Key (ItemId) References Item(Id) 
) 

Insert into Item (QuestionId, Sequence) 
Values (1, 1), 
(1, 2) 

Insert into UnitType(Action, TriggerType) 
Values (1, 'Changed') 

Insert into Unit (TypeId, Message) 
Values (1, 'Hello World'), 
(1, 'Hello World') 

Insert into UnitCondition(UnitId, Value, ItemId) 
Values (1, 'Test', 1), 
(1, 'Hello', 2), 
(2, 'Test', 1), 
(2, 'Hello', 2) 

我創建了一個SqlFiddle,演示了此問題的一種簡單形式。

甲單位被認爲是與在單元中的所有(非-ID)字段,以及對組合在每一個細節被精確匹配該股所有條件重複。考慮到這,如XML - 一個Unit節點(包含單位信息和條件的子集)是獨一無二的,如果沒有其他Unit節點存在是一個確切的字符串複製

Select 
    Action, 
    TriggerType, 
    U.TypeId, 
    U.Message, 
    (
     Select C.Value, C.ItemId, I.QuestionId, I.Sequence 
     From UnitCondition C 
     Inner Join Item I on C.ItemId = I.Id 
     Where C.UnitId = U.Id 
     For XML RAW('Condition') 
) as Conditions 
from UnitType T 
    Inner Join Unit U on T.Id = U.TypeId 
For XML RAW ('Unit'), ELEMENTS 

但我有問題,我似乎無法讓每個單元的XML顯示爲新記錄,而且我不確定如何比較單元節點以查找重複。

如何運行此查詢以確定集合中是否存在重複的Xml Unit節點?

+0

你可以添加你想要的輸出嗎? – Tanner 2014-08-29 14:24:36

+0

雖然輸出格式我不那麼討厭,但只要我可以比較兩個單位並確定唯一性 - 無論這是一個包含所有值的單個字符串,還是包含所有行的所有列組合的大表,我不介意。 – 2014-08-29 14:26:26

+0

這很好,但是根據你的小提琴的輸出結果,我不確定你是如何識別唯一性的,所以如果你可以手工製作輸出應該是什麼樣的,你可能會得到更多的幫助來產生輸出。 – Tanner 2014-08-29 14:31:27

回答

0

所以,我設法弄清楚什麼我需要這樣做。雖然這有點笨重。

首先,您需要將Xml Select語句包裝在另一個選擇單元表中,以確保我們最終只用xml表示該單元。

Select 
Id, 
(
    Select 
    Action, 
    TriggerType, 
    IU.TypeId, 
    IU.Message, 
    (
     Select C.Value, I.QuestionId, I.Sequence 
     From UnitCondition C 
      Inner Join Item I on C.ItemId = I.Id 
     Where C.UnitId = IU.Id 
     Order by C.Value, I.QuestionId, I.Sequence 
     For XML RAW('Condition'), TYPE 
    ) as Conditions 
    from UnitType T 
    Inner Join Unit IU on T.Id = IU.TypeId 
    WHERE IU.Id = U.Id 
    For XML RAW ('Unit') 
) 
From Unit U 

然後,你可以把它包裝在另一個select中,把xml按內容分組。

Select content, count(*) as cnt 
From 
    (
    Select 
     Id, 
     (
     Select 
      Action, 
      TriggerType, 
      IU.TypeId, 
      IU.Message, 
      (
       Select C.Value, C.ItemId, I.QuestionId, I.Sequence 
       From UnitCondition C 
       Inner Join Item I on C.ItemId = I.Id 
       Where C.UnitId = IU.Id 
       Order by C.Value, I.QuestionId, I.Sequence 
       For XML RAW('Condition'), TYPE 
     ) as Conditions 
     from UnitType T 
      Inner Join Unit IU on T.Id = IU.TypeId 
     WHERE IU.Id = U.Id 
     For XML RAW ('Unit') 
    ) as content 
    From Unit U 
) as data 
group by content 
having count(*) > 1 

這將允許您將整個內容相同的整個單元分組。

要注意的一點是,要測試「唯一性」,您需要確保內部Xml選擇的數據始終相同。爲此,您應該對相關數據(即xml中的數據)進行排序以確保一致性。你應用的順序並不重要,只要兩個相同的集合以相同的順序輸出即可。

0

如果您想確定記錄是否重複,則不需要將所有值組合成一個字符串。你可以用這樣的ROW_NUMBER功能做到這一點:

SELECT 
    Action, 
    TriggerType, 
    U.Id, 
    U.TypeId, 
    U.Message, 
    C.Value, 
    I.QuestionId, 
    I.Sequence, 
    ROW_NUMBER() OVER (PARTITION BY <LIST OF FIELD THAT SHOULD BE UNIQUE> 
         ORDER BY <LIST OF FIELDS>) as DupeNumber 
FROM UnitType T 
    Inner Join Unit U on T.Id = U.TypeId 
    Inner Join UnitCondition C on U.Id = C.UnitId 
    Inner Join Item I on C.ItemId = I.Id; 

如果DupeNumber大於1,則記錄ID重複。

+0

這不是真的會工作在條件中有可變數量的記錄,是嗎?我需要知道* whole *單元是否是唯一的,而不是其中的特定記錄。 – 2014-08-29 14:49:08

+0

你是什麼意思「可變數量的記錄」?您只能在列表中包含代表您的主鍵的字段。 – Bulat 2014-08-29 14:53:47

+0

單元可以有任意數量的UnitCondition記錄。整個集合必須是唯一的:多個單位可能具有相同的給定記錄,但單位中的所有記錄在各方面都不應該完全相同。 – 2014-08-29 14:55:04

0

試試這個
這將發現對不唯一
如何構建成你最終的答案 - 不知道 - 但可能開始

select u1.id, u2.id 
    from unit as u1 
    join unit as u2 
    on ui.ID < u2.id 
    join UnitCondition uc1 
    on uc1.unitID = u1.ID 
    full outer join uc2 
    on uc2.unitID = u2.ID 
    and uc2.itemID = uc1.itemID 
where uc2.itemID is null or uc1.itemID is null