1
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

Both of these examples copy all 5 records to the new table.

I only want to see one unique fname so only one Kevin should show up.

Why don't these work, or is there a better way to do it?

It seems like such a simple thing.

4

4 回答 4

2

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

INSERT INTO #B
SELECT a.fname, MIN(a.lname) 
FROM #A a
GROUP BY a.fname
于 2013-06-03T01:25:26.897 回答
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

演示

于 2013-06-03T00:30:41.897 回答
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 的下一个元组的查询。插入总是在查询被完全评估之后完成。

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

INSERT INTO #B SELECT distinct * from #A;

--dmg

于 2013-06-03T01:15:00.637 回答
0

只需在选择查询上使用 DISTINCT :

INSERT INTO TARGET_TABLE
SELECT DISTINCT * FROM
(
     -- some big query
) x
于 2013-06-03T01:25:11.490 回答