将记录从一个表复制到另一个表而不重复

时间:2013-06-02 22:24:14

标签: sql sql-server-2008

IF object_id('tempdb..#A')  IS NOT NULL DROP TABLE #A
IF object_id('tempdb..#B')  IS NOT NULL DROP TABLE #B
CREATE TABLE #A (fname varchar(20), lname varchar(20))
CREATE TABLE #B (fname varchar(20), lname varchar(20))

INSERT INTO #A
SELECT 'Kevin', 'XP'
UNION ALL
SELECT 'Tammy', 'Win7'
UNION ALL
SELECT 'Wes', 'XP'
UNION ALL 
SELECT 'Susan', 'Win7'
UNION ALL
SELECT 'Kevin', 'Win7'


SELECT * FROM #A

INSERT INTO #B
SELECT a.fname, a.lname FROM #A a
WHERE a.fname NOT IN (SELECT fname from #B)

SELECT * FROM #B

DELETE FROM #B
INSERT INTO #B
SELECT a.fname, a.lname FROM #A a
LEFT OUTER JOIN #B b ON a.fname = b.fname
WHERE a.fname NOT IN (SELECT fname from #B)

SELECT * FROM #B

这两个示例都将所有5条记录复制到新表中。

我只想看到一个独特的fname,所以只有一个Kevin应该出现。

为什么这些不起作用,还是有更好的方法呢?

这似乎很简单。

4 个答案:

答案 0 :(得分:2)

如果Win7和XP都存在,这将创建具有唯一fname的行并获取Win7。

INSERT INTO #B
SELECT a.fname, MIN(a.lname) 
FROM #A a
GROUP BY a.fname

答案 1 :(得分:1)

根据评论,假设W出现在X之前,那么你应该可以做到

INSERT INTO #B
SELECT fname, lname
FROM (
    SELECT fname, lname,
           ROW_NUMBER() OVER(PARTITION BY fname ORDER BY lname) r
    FROM #A
) t
WHERE r=1

demo

答案 2 :(得分:1)

回答你的问题,为什么你的查询不起作用?

INSERT INTO #B
SELECT a.fname, a.lname FROM #A a
WHERE a.fname NOT IN (SELECT fname from #B)

此操作在两个不同的操作中进行评估。首先,执行查询的SELECT部分​​。它返回一个表。在这一点#B是空的,因此,#A中的每个元组都将成为此结果的一部分。然后,一旦计算出该结果,就将该结果插入到#B中。 #B将以#A的副本结束。

DBMS没有插入一个元组,然后重新评估#A的下一个元组的查询,因为你的问题似乎暗示了。在完全评估查询之后,总是完成插入。

如果您的目标是在#B中插入#A中没有重复的元组,那么有很多方法可以做到这一点。其中之一是:

INSERT INTO #B SELECT distinct * from #A;

- DMG

答案 3 :(得分:0)

只需对选择查询使用DISTINCT:

INSERT INTO TARGET_TABLE
SELECT DISTINCT * FROM
(
     -- some big query
) x