2013-05-01 52 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;