2012-04-03 58 views
0

我有一張表,其中大部分列都填充了數據。在那張表中,我有4列的行,我有重複的數據。我想要做這樣的事情:SQL Server:用於行組的複雜操作唯一代碼

檢查所有的行,將這四列的所有數據(一組=這四列的一個唯一數據)進行分組,並在最後一列簽名給他們UniqueCodeUniqueCode是爲組。

所以,當我有這樣的事情:

Name Street HouseNumber PostCode UniqueCode 
Cos Cos Cos   Cos 
Cos Cos Cos   Cos 

我要填寫UniqueCode與此相同的代碼。我想寫一個查詢,清除所有當前的uniqueCode並填寫新的和寫入trigger(我稱它是正確的?),它對新添加的行也做同樣的事情。

有可能在sql中寫入該行爲?

或者我需要在我的程序代碼中執行它?

你能幫我嗎?

對不起,我的英語不好。

+1

這是什麼版本的Sql Server? – 2012-04-03 09:32:28

回答

0

假設你有類似這樣的一個表:

create table Persons 
(
    ID int identity primary key, 
    Name varchar(100), 
    Street varchar(100), 
    HouseNumber int, 
    PostCode varchar(100), 
    UniqueCode uniqueidentifier 
) 

您需要創建認定已經進入具有相同的複合鍵的人觸發:

create trigger AssignPersonGroup on Persons 
after insert, update 
as 
    set nocount on 

    update Persons 
    set UniqueCode = 
    isnull(
     (select top 1 UniqueCode from Persons 
     where UniqueCode is not null 
     and Inserted.Name = Persons.Name 
     and Inserted.Street = Persons.Street 
     and Inserted.HouseNumber = Persons.HouseNumber 
     and Inserted.PostCode = Persons.PostCode) 
     , newid()) 
    from Inserted inner join Persons 
     on Inserted.ID = Persons.ID 

並假設這將是數據:

insert into persons (Name, Street, HouseNumber, PostCode) 
values ('Zagor', 'Darkwood', 23, '01010') 
insert into persons (Name, Street, HouseNumber, PostCode) 
values ('Zagor', 'Darkwood', 23, '01010') 
insert into persons (Name, Street, HouseNumber, PostCode) 
values ('Chico', 'Darkwood', 23, '01010') 

然後

select * 
from Persons 

將提供:

update persons 
    set uniquecode = newid() 

update Persons 
    set uniqueCode= 
    (
     select top 1 uniqueCode 
     from Persons groups 
     where UniqueCode is not null 
     and groups.Name = Persons.Name 
     and groups.Street = Persons.Street 
     and groups.HouseNumber = Persons.HouseNumber 
     and groups.PostCode = Persons.PostCode 
     order by ID 
    ) 

他們是分開的,因爲SQL Server執行標量表達式之前加入:如果執行以下兩個更新

ID Name Street HouseNumber PostCode UniqueCode 
1 Zagor Darkwood   23 01010 A113D12D-F730-42DD-B3EE-AC33E34C0679 
2 Zagor Darkwood   23 01010 A113D12D-F730-42DD-B3EE-AC33E34C0679 
3 Chico Darkwood   23 01010 FD0739AF-525C-42C2-B929-0AB8EEAC3A73 

您現有的數據將被更新。我的第一個承擔這一點是更新查詢與所有列的派生表分組並添加newid()列,但作爲內部連接到人表執行第一個ids是唯一的每一行再次。

在執行此操作之前禁用觸發器,稍後重新啓用它。 uniqueCode不應該在程序中設置,只能在觸發器中設置。您需要(名稱,街道,HouseNumber,PostCode)和UniqueCode上的另一個組合索引。

除此之外,我已經看到你關於這個項目的其他問題。你想做什麼?我不確定小學和高中桌子之間的關係的性質。如果你想通過某個人連接他們,那麼你應該有一個帶有身份主鍵的人表。兩張表都會引用這一個,並且在識別某人的學術路徑時你沒有問題:-)

+0

嗨,thx回覆。這就是我所需要的。但是你關於小學和高中關係的問題迫使我去思考。我試圖做的是通過獨特的代碼鏈接所有在同一建築物中的學校。問題是,我有一個像上面提到的列和另一個重要列的列表。在我的課程中,我需要這些學校的名單,當我從他們那裏選擇一個時,我需要相關學校的名單。所有相關的學校都需要獨特的代碼(整個組)。我知道最好的方法是通過單獨的表(地址或類似的東西),但我不怎麼轉換。 – 2012-04-10 15:44:37

+0

另一個問題。我不想要這麼長時間的指導。我需要5-6個字母的代碼。我怎樣才能做到這一點? – 2012-04-10 16:02:08

+0

@JakubDropia我相信它應該是一樣的。要測試數據,請發出以下查詢:'通過名稱,街道,HouseNumber,PostCode具有count(獨特唯一碼)> 1',從MyTable組中選擇Name,Street,HouseNumber,PostCode。返回的記錄將顯示具有多於一個代碼的地址。至於短代碼,您可以使用int,但必須從專用計數器表中分配下一個數字。你是對的 - 地址表是最好的解決方案。我在評論中沒有足夠的位置來向你展示如何,如果你想這樣做,就讓我掉線。 – 2012-04-10 17:39:23