除了有条件的表

时间:2013-05-01 15:57:35

标签: sql sql-server

我们有两个表,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)

这是有效的,但实际上有很多列,我能用Except做吗?

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

这是版本除外,但是这个版本没有考虑到我们需要忽略版本栏。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分: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;