2011-09-29 76 views
2

我試圖從視圖中插入唯一值到表中。我有一個表,如下: 的「fromView」在護照插入不同的值SQL Server

id | passport | name | surname | address 
1  44543  John Smith  xxxxx 
2  10001  Mike Thomps avasfa 
3  10001  Mike Thomps avasfa 
4  10001  Mike Thomps avasfa 
5  14221  Robert Martinez lkjij3 

我「toTable」具有相同的數據結構,但在護照列唯一約束沒有唯一約束。

我插入查詢是這樣的:

INSERT into toTable (id, passport, name, surname, address) 
SELECT (id, passport, name, surname, address) 
FROM fromView a 
WHERE passport IS NOT NULL AND NOT EXISTS (SELECT * 
              FROM toTable b 
              WHERE b.passport = a.passport) 

但是這給我下面的錯誤:

不能在對象'toTable具有唯一索引「toTable_Passport_Unique」插入重複鍵行。

所以,我不知道如何插入唯一值到我的表中。在此先感謝

+1

你正在使用哪些DBMS? –

回答

4

您可以通過運行該查詢得到具有多個條目的所有護照的列表:

Select Passport, Count (*) NumEntries 
From fromTable 
Group by Passport 
Having Count (*) > 1 

然後,你必須決定如何處理這些重複行做。運行下面的查詢看到完整的一行這些重複:

Select * 
From fromTable 
Where Passport In 
(
    Select Passport, Count (*) NumEntries 
    From fromTable 
    Group by Passport 
    Having Count (*) > 1 
) 
Order by Passport 

比方說,你決定爲每個插入的護照最新的排走(這意味着標識將是最高的),這個查詢會給你你需要的數據。

Select T1.* 
From fromTable T1 
Where Id In 
(
    Select Max (Id) Id 
    From fromTable 
    Group by Passport 
) 

您可以插入使用

INSERT into toTable (id, passport, name, surname, address) 
Select T1.* 
From fromTable T1 
Where Id In 
(
    Select Max (Id) Id 
    From fromTable 
    Group by Passport 
) 
+0

這也工作,並與更簡單的句子,謝謝! – grteibo

0

如果我們可以假設,在相同passport,我們將具有相同的namesurnameaddress,我們只希望最近的(最高) id然後嘗試,

INSERT INTO toTable (id, passport, name, surname, address) 
SELECT max(id), passport, name, surname, address 
FROM fromTable 
--optional WHERE clause in case there's already data in toTable: 
WHERE passport NOT IN (SELECT to.passport from toTable [to]) 
GROUP BY passport, name, surname, address 
+0

@寡婦 - 這是一個不好的假設 –

+0

我不會說它*那*不好 - 畢竟我們正在處理護照,並且示例表包含相同的假設。 – Widor

+0

人們隨時都在變更地址,有時還會變更地址。我不想做這個假設。 –

2
insert into toTable (id, passport, name, surname, address) 
select id, passport, name, surname, address 
from (
     select *, 
      row_number() over(partition by passport order by id) as rn 
     from fromTable 
    ) as T 
where rn = 1 
+0

我真的不知道row_numer()和分區,但這是行得通的,謝謝! – grteibo

+0

@grteibo - 在這裏閱讀更多關於它的信息。 http://msdn.microsoft.com/en-us/library/ms186734.aspx –

0
insert into toTable (id, name, surname, addr, passport) 
    select 
    testA1.id, testA1.name, testA1.surname, testA1.addr, testA1.passport 
    from 
    fromTable as testA1 right join (select min(id) AS distinctID, passport from fromTable group by passport) as testA2 on 
    testA2.distinctID = testA1.id