比较两个数据库表

时间:2009-09-15 18:09:47

标签: sql

我需要比较两个表中的所有字段......它们是相同的大小(四行)并且具有相同数量的列(五列)。我正在寻找的逻辑是......

If (table 1 = table 2)
do something
Else
do something else

在SQL中我写了类似......

的内容
If (Select * from table 1 = select * from table 2)
do something
else
do something else

这不起作用!!!

我尝试过做EXCEPT和UNION ALL语句......但是我不需要知道不同的行甚至是不同的值,我只需要知道BOOLEAN'是'表是不同的'或'不,他们不是。

6 个答案:

答案 0 :(得分:9)

答案 1 :(得分:1)

[修订]

以下是使用“SELECT ... EXCEPT ...”执行此操作的方法:

IF not exists(select *
               from MyTable
              except select *
               from MyOtherTable)
 and not exists(select *
               from MyOtherTable
              except select *
               from MyTable)
    PRINT 'They match'
ELSE
    PRINT 'They do not match'

写入速度要快一些,除非您需要比较少于所有列。这将需要四次表扫描,因此您应该将性能与UNION策略进行比较和对比。根据我的经验SELECT ... EXCEPT ...往往运行得很快 - 我猜是因为所有的联合和列比较都在内部发生。

答案 2 :(得分:0)


ALTER PROCEDURE dbo.CompareTables
(
    @table1 VARCHAR(100), 
    @table2 VARCHAR(100), 
    @T1ColumnList VARCHAR(1000),
    @T2ColumnList VARCHAR(1000) = ''
)
AS
/*
    Table1, Table2 are the tables or views to compare.
    T1ColumnList is the list of columns to compare, from table1.
    Just list them comma-separated, like in a GROUP BY clause.
    If T2ColumnList is not specified, it is assumed to be the same
    as T1ColumnList.  Otherwise, list the columns of Table2 in
    the same order as the columns in table1 that you wish to compare.

The result is all rows from either table that do NOT match
the other table in all columns specified, along with which table that
row is from.

*/

DECLARE @SQL VARCHAR(8000)

IF @t2ColumnList = '' SET @T2ColumnList = @T1ColumnList

SET @SQL = 'SELECT ''' + @table1 + ''' AS TableName, ' + @t1ColumnList + ' FROM ' + @Table1 + ' UNION ALL SELECT ''' + @table2 + ''' As TableName, ' + @t2ColumnList + ' FROM ' + @Table2

SET @SQL = 'SELECT Max(TableName) as TableName, ' + @t1ColumnList + ' FROM (' + @SQL + ') A GROUP BY ' + @t1ColumnList + ' HAVING COUNT(*) = 1'

EXEC ( @SQL)

答案 3 :(得分:0)

这样的事情应该有效,使用Exist / Not Exists - 然后由你决定如何判断是否获得一行为True或False。 实际语法取决于数据库。这是Transact-SQL

Create table A
( one int, two int, three int , four int)

Create table B
( one int, two int, three int, four int)

insert A values ( 1,2,3,4)
insert B values( 1,2,3,4)

select * from A a
where exists ( select 1 from B b where 
    a.one = b.one
and a.two = b.two
and a.three = b.three
and a.four = b.four)

一二三四


1 2 3 4

答案 4 :(得分:0)

如果您只想比较几列(或2-5列的表),您可以使用此FULL JOIN(未经测试):

select      COUNT(*) AS UnmatchedRows
from        table1 t1
full join   table2 t2
        on  t1.col1 = t2.col1
        and t1.col2 = t2.col2
        and t1.col3 = t2.col3
        and t1.col4 = t2.col4
        and t1.col5 = t2.col5
where       COALESCE(t1.col1, t2.col1) IS NULL

德鲁伊引用的解决方案仍然很酷。

答案 5 :(得分:0)

每次扩展Wiretaps代码时,都会厌倦写下所有新列。

" exec CompareTables table1,table2 "将更轻松地完成工作:

CREATE PROCEDURE [dbo].[CompareTables](@table1 varchar(100), 

 @table2 Varchar(100))

AS



-- Table1, Table2 are the tables or views to compare.

-- The columns of both tables are acquired from the table definition
-- ordered by the ordinal position 

-- The result is all rows from either table that do NOT match

-- the other table in all columns specified, along with which table that

-- row is from.



declare @SQL varchar(8000);
declare @T1ColumnList varchar(1000);

SET @T1ColumnList = (
Select TOP 1 Stuff(
        (
        Select ',' + C.COLUMN_NAME
        From INFORMATION_SCHEMA.COLUMNS As C
        Where C.TABLE_SCHEMA = T.TABLE_SCHEMA
            And C.TABLE_NAME = T.TABLE_NAME
        Order By C.ORDINAL_POSITION
        For Xml Path('')
        ), 1, 1, '') As Columns
From INFORMATION_SCHEMA.TABLES As T WHERE T.TABLE_NAME=@table1)
declare @T2ColumnList varchar(1000);
SET @T2ColumnList = (
Select TOP 1 Stuff(
        (
        Select ',' + C.COLUMN_NAME
        From INFORMATION_SCHEMA.COLUMNS As C
        Where C.TABLE_SCHEMA = T.TABLE_SCHEMA
            And C.TABLE_NAME = T.TABLE_NAME
        Order By C.ORDINAL_POSITION
        For Xml Path('')
        ), 1, 1, '') As Columns
From INFORMATION_SCHEMA.TABLES As T WHERE T.TABLE_NAME=@table2)



set @SQL = 'SELECT ''' + @table1 + ''' AS TableName, ' + @t1ColumnList +

 ' FROM ' + @Table1 + ' UNION ALL SELECT ''' + @table2 + ''' As TableName, ' +

 @t2ColumnList + ' FROM ' + @Table2



set @SQL = 'SELECT Max(TableName) as TableName, ' + @t1ColumnList +

 ' FROM (' + @SQL + ') A GROUP BY ' + @t1ColumnList + 

 ' HAVING COUNT(*) = 1'



exec ( @SQL)


GO