2013-05-01 50 views
1

表中,我們有兩個表,ID是主鍵除非獲得條件

Old 
{ 
id 
name 
school 
... 
version 
} 

New 
{ 
id 
name 
school 
... 
version 
} 

我想找到兩個表相同的ID有相同的密鑰,但不同的其他列,而忽略版本。

Select * From [New] n Inner Join On [Old] o On n.id = o.id 
Where n.name != o.name OR n.school!=o.school ....(Do all the columns without version) 

這是工作,但實際上有很多列,我可以用它做嗎?

SELECT * FROM [New] WHERE id IN (SELECT id FROM [New] EXCEPT (SELECT id FROM [Old])) 

這是除了版本,但這一個不認爲我們需要忽略版本列。

+0

是在-1 ....只是改回了0,因爲這樣的問題是非常有用 – whytheq 2013-05-02 10:52:48

+0

3:問題,0:被接受的答案。你應該開始接受答案。 Gordon Linoff的回答有六個投票。爲什麼這個答案不被接受? – 2013-05-10 11:26:42

回答

6

這裏是解決方案的框架:

select <columnlist> 
    from new 
    where id in (select id from old) 
    except 
    select <columnlist> 
    from old 

要獲得<columnlist>,您可以手動輸入。或者,您可以從information_schema.columns進行查詢。或者,你可以去到SQL Server Management Studio並執行以下操作:

  • 打開在對象資源管理器數據庫
  • 打開「表格」
  • 開放的利息(New
  • 單擊表在「列」(不需要打開它)並將其拖到查詢窗口中

所有列出現。然後刪除你不想要的version

0
SET STATISTICS IO ON; 
SET NOCOUNT ON; 

DECLARE @Old TABLE (
    Id INT PRIMARY KEY, 
    Col1 INT NULL, 
    Col2 VARCHAR(50) NULL 
); 
DECLARE @New TABLE (
    Id INT PRIMARY KEY, 
    Col1 INT NULL, 
    Col2 VARCHAR(50) NULL 
); 

INSERT @Old (Id, Col1, Col2) 
SELECT 1, 11, 'A' 
UNION ALL SELECT 2, 22, 'B' 
UNION ALL SELECT 3, 33, 'C' 
UNION ALL SELECT 4, NULL, NULL 
UNION ALL SELECT 5, NULL, NULL; 

INSERT @New (Id, Col1, Col2) 
SELECT 1, 11, 'A' 
UNION ALL SELECT 2, 222, 'B' 
UNION ALL SELECT 3, NULL, 'C' 
UNION ALL SELECT 4, 44, NULL 
UNION ALL SELECT 5, NULL, NULL; 

PRINT 'Begin of test'; 

PRINT '@Old:'; 
SELECT * FROM @Old; 

PRINT '@New:'; 
SELECT * FROM @New; 

PRINT 'Last SELECT:' 
SELECT * 
FROM (
    SELECT x.Id, x.Col1, x.Col2, x.Rowtype, 
      DENSE_RANK() OVER(PARTITION BY x.Id ORDER BY x.Col1, x.Col2) AS Rnk1, 
      DENSE_RANK() OVER(PARTITION BY x.Id ORDER BY x.Col1 DESC, x.Col2 DESC) AS Rnk2 
    FROM (
     SELECT o.Id, o.Col1, o.Col2, 1 AS RowType 
     FROM @Old o 
     UNION ALL 
     SELECT n.Id, n.Col1, n.Col2, 2 AS RowType 
     FROM @New n 
    ) x 
) y 
--WHERE y.RowType=1 AND (y.Rnk1=2 OR y.Rnk2=2) -- Only old rows 
WHERE y.RowType=2 AND (y.Rnk1=2 OR y.Rnk2=2) -- Only new rows 

PRINT 'End of test'; 

結果:

Id Col1 Col2 Rowtype Rnk1 Rnk2 
-- ---- ---- ------- ---- ---- 
2 222 B 2  2 1 
3 NULL C 2  1 2 
4 44 NULL 2  2 1 

消息:

Begin of test 
@Old: 
Table '#671F4F74'. Scan count 1, logical reads 2 
@New: 
Table '#6AEFE058'. Scan count 1, logical reads 2 
Last SELECT: 
Table '#6AEFE058'. Scan count 1, logical reads 2 
Table '#671F4F74'. Scan count 1, logical reads 2 
End of test 
0

(不知道爲什麼,我懷疑它!),但我無法想像戈登的回答。

我設置下面的例子來證明給自己:

CREATE TABLE #old (id INT,y INT,z INT); 
INSERT INTO #old 
    values 
    (1,2,3), 
    (2,3,4), 
    (5,6,7), 
    (8,9,10); 

CREATE TABLE #new (id INT,y INT,z INT); 
INSERT INTO #new 
    values 
    (1,2,3), 
    (2,30,4), 
    (5,6,7), 
    (8,9,100); 

--Existing script 
SELECT n.id, n.y, n.z 
FROM #new n 
    INNER JOIN #old o 
    ON n.id = o.id 
WHERE 
    n.y != o.y 
    OR 
    n.z != o.z; 

--Gordon's answer 
SELECT id, y, z 
FROM #new 
WHERE id IN (SELECT id from #old) 
EXCEPT 
SELECT id, y, z 
FROM #old;