2011-09-29 3 views
2

J'essaie d'insérer des valeurs uniques dans une table à partir d'une vue. J'ai une table comme ci-dessous: le « fromView » n'a pas contrainte unique dans le passeportInsérer des valeurs distinctes 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 

mon « Totable » a la même structure de données, mais avec une contrainte unique dans la colonne de passeport.

ma requête d'insertion est la suivante:

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) 

mais cela me donne l'erreur ci-dessous:

Impossible d'insérer la ligne clé dans l'objet 'Totable' avec index unique 'toTable_Passport_Unique'.

Donc, je ne sais pas comment insérer des valeurs uniques dans ma table. Merci à l'avance

+1

Quel SGBD utilisez-vous? –

Répondre

4

Vous pouvez obtenir une liste de tous les passeports avec plusieurs entrées en exécutant cette requête:

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

Ensuite, vous devez décider quoi faire avec ces lignes en double. Exécutez la requête suivante pour voir la ligne complète de ces doublons:

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

Supposons que vous décidez d'aller avec la nouvelle ligne insérée pour chaque passeport (ce qui signifie Id serait le plus élevé), cette requête vous donnera la les données dont vous avez besoin.

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

Vous pouvez insérer à l'aide

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

cela fonctionne aussi et avec des phrases plus simples merci !! – grteibo

0

Si nous pouvons supposer que pour la même passport, nous aurons la même name, surname et address, et nous voulons que le plus récent (le plus élevé) id puis essayez,

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

@Widow - c'est une mauvaise hypothèse –

+0

Je ne dirais pas que c'est * que * mauvais - nous avons affaire à des passeports, après tout, et la table d'exemple comprend la même hypothèse. – Widor

+0

Les gens changent d'adresse tout le temps, et parfois les noms. Je ne voudrais pas faire cette supposition. –

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

Je ne sais vraiment pas sur row_numer() et la partition, mais cela fonctionne, merci! – grteibo

+0

@grteibo - En savoir plus à ce sujet ici. 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 
Questions connexes