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]))

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

4

3 回答 3

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)
  • 点击“Columns”(无需打开),拖入查询窗口

所有列都会出现。然后删除version你不想要的。

于 2013-05-01T16:17:14.587 回答
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;
于 2013-05-02T08:31:20.710 回答
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
于 2013-05-01T18:12:15.833 回答