2013-06-02 223 views
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 

這兩個示例都將所有5條記錄複製到新表中。將記錄從一張表複製到另一張沒有重複記錄

我只想看到一個獨特的名字,所以只有一個凱文應該出現。

爲什麼不這些工作,或者有更好的方法來做到這一點?

這似乎是這樣一個簡單的事情。

+1

但哪個'凱文'應該進入新表? –

+0

Windows7如果同時存在 – kevro

+0

爲什麼選擇Windows7?也許你可以發佈表應該看起來像什麼(以及爲什麼) – Rob

回答

2

這將創建行具有獨特FNAME和採取的Win7是否Win7和XP都存在。

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

謝謝。我沒有意識到MIN()也適用於字符串。在我上面的評論中,我使用CASE語句轉換爲數字,然後選擇所需的數字。這很容易。 – kevro

1

按照意見,因爲WX之前,那麼你應該能夠做到

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

+0

我喜歡這個,但MIN(lname)更簡單。 Thx – kevro

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

+0

INSERT INTO #B SELECT DISTINCT仍然複製了5條記錄。 – kevro

+0

對不起,我誤解了你的問題。我以爲你想要獨特的元組,不能區分只有一個屬性。我同意插入GROUP by是最好的解決方案。 – dmg

0

只需使用DISTINCT在選擇查詢:

INSERT INTO TARGET_TABLE 
SELECT DISTINCT * FROM 
(
    -- some big query 
) x 
相關問題