[sql] 두 테이블의 SQL 비교 데이터

I 2 개 테이블을 TableA하고 TableB두 테이블을 예를 들면 열 동일한 형식을 갖는 TableATableB열이

A B C D E F

여기서 A와 B는 기본 키입니다.

경우 있는지 확인하기 위해 SQL을 작성하는 방법 TableATableB그 동일한 기본 키가 모든 컬럼에서 정확히 같은 값을 포함합니다.

이는이 두 테이블이 정확히 동일한 데이터를 가지고 있음을 의미합니다.



답변

DBMS에서 사용하는 SQL의 종류에 따라 “MINUS”또는 “EXCEPT”가 가능해야합니다.

select * from tableA
minus
select * from tableB

쿼리가 행을 반환하지 않으면 데이터가 정확히 동일합니다.


답변

관계 연산자 사용 :

SELECT * FROM TableA
UNION
SELECT * FROM TableB
EXCEPT
SELECT * FROM TableA
INTERSECT
SELECT * FROM TableB;

변경 EXCEPTMINUS대한 Oracle.

약간 까다로운 점 : 위의 내용은 연산자 우선 순위에 의존하며 SQL 표준에 따라 구현에 따라 다르므로 YMMV입니다. 우선 순위가 다음과 같은 SQL Server에서 작동합니다.

  1. 괄호 안의 식
  2. INTERSECT
  3. EXCEPT그리고 UNION왼쪽에서 오른쪽으로 평가했다.


답변

dietbuddha는 좋은 대답을 가지고 있습니다. MINUS 또는 EXCEPT가없는 경우 한 가지 옵션은 테이블간에 모두 유니온을 수행하고 모든 열과 함께 그룹화하고 모든 항목이 두 개 있는지 확인하는 것입니다.

SELECT col1, col2, col3
FROM
(SELECT * FROM tableA
UNION ALL
SELECT * FROM tableB) data
GROUP BY col1, col2, col3
HAVING count(*)!=2


답변

SELECT c.ID
FROM clients c
WHERE EXISTS(SELECT c2.ID
FROM clients2 c2
WHERE c2.ID = c.ID);

두 테이블에서 동일한 모든 ID를 반환합니다. 차이점을 얻으려면 EXISTS를 NOT EXISTS로 변경하십시오.


답변

언젠가 스크립트를 가져 와서 각 항목의 출처를 표시하도록 수정했습니다.

DECLARE @table1 NVARCHAR(80)= 'table 1 name'
DECLARE @table2 NVARCHAR(80)= 'table 2 name'
DECLARE @sql NVARCHAR (1000)

SET @sql =
'
SELECT ''' + @table1 + ''' AS table_name,* FROM
(
SELECT * FROM ' + @table1 + '
EXCEPT
SELECT * FROM ' + @table2 + '
) x

UNION

SELECT ''' + @table2 + ''' AS table_name,* FROM
(
SELECT * FROM ' + @table2 + '
EXCEPT
SELECT * FROM ' + @table1 + '
) y
'

EXEC sp_executesql @stmt = @sql


답변

완료하기 위해 except 메소드를 사용하여 저장된 proc은 2 개의 테이블을 비교하고 3 개의 오류 상태를 가진 동일한 테이블에 결과를 제공합니다. ADD, DEL, GAP 테이블은 동일한 PK를 가져야합니다. 1 개 또는 2 개의 테이블을 비교할 2 개의 테이블과 필드를 선언합니다.

다음과 같이 사용하십시오. ps_TableGap ‘tbl1’, ‘Tbl2’, ‘fld1, fld2, fld3’, ‘fld4’fld5’fld6′(선택 사항)

/****** Object:  StoredProcedure [dbo].[ps_TableGap]    Script Date: 10/03/2013 16:03:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Author:       Arnaud ALLAVENA
-- Create date: 03.10.2013
-- Description: Compare tables
-- =============================================
create PROCEDURE [dbo].[ps_TableGap]
    -- Add the parameters for the stored procedure here
    @Tbl1 as varchar(100),@Tbl2 as varchar(100),@Fld1 as varchar(1000), @Fld2 as varchar(1000)= ''
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.

    SET NOCOUNT ON;
--Variables
--@Tbl1 = table 1
--@Tbl2 = table 2
--@Fld1 = Fields to compare from table 1
--@Fld2 Fields to compare from table 2
Declare @SQL varchar(8000)= '' --SQL statements
Declare @nLoop int = 1 --loop counter
Declare @Pk varchar(1000)= '' --primary key(s) 
Declare @Pk1 varchar(1000)= '' --first field of primary key
declare @strTmp varchar(50) = '' --returns value in Pk determination
declare @FldTmp varchar (1000) = '' --temporarily fields for alias calculation

--If @Fld2 empty we take @Fld1
--fields rules: fields to be compare must be in same order and type - always returns Gap
If @Fld2 = '' Set @Fld2 = @Fld1

--Change @Fld2 with Alias prefix xxx become _xxx 
while charindex(',',@Fld2)>0
begin
    Set @FldTmp = @FldTmp + (select substring(@Fld2,1,charindex(',',@Fld2)-1) + ' as _' + substring(@Fld2,1,charindex(',',@Fld2)-1) + ',')
    Set @Fld2 = (select ltrim(right(@Fld2,len(@Fld2)-charindex(',',@Fld2))))
end
Set @FldTmp = @FldTmp + @Fld2 + ' as _' + @Fld2
Set @Fld2 = @FldTmp

--Determinate primary key jointure
--rule: same pk in both tables
Set @nLoop = 1
Set @SQL = 'Declare crsr cursor for select COLUMN_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '''
 + @Tbl1 + ''' or TABLE_SCHEMA + ''.'' + TABLE_NAME = ''' + @Tbl1 +  ''' or TABLE_CATALOG + ''.'' + TABLE_SCHEMA + ''.'' + TABLE_NAME = ''' + @Tbl1
 + ''' order by ORDINAL_POSITION'
exec(@SQL)
open crsr
fetch next from crsr into @strTmp
while @@fetch_status = 0
begin
    if @nLoop = 1
    begin
        Set @Pk = 's.' + @strTmp + ' = b._' + @strTmp
        Set @Pk1 = @strTmp
        set @nLoop = @nLoop + 1
    end
    Else
    Set @Pk = @Pk + ' and s.' + @strTmp + ' = b._' + @strTmp
fetch next from crsr into @strTmp

end
close crsr
deallocate crsr

--SQL statement build
set @SQL = 'select case when s.' + @Pk1 + ' is null then ''Del'' when b._' + @Pk1 + ' is null then ''Add'' else ''Gap'' end as TypErr, '''
set @SQL = @SQL + @Tbl1 +''' as Tbl1, s.*, ''' + @Tbl2 +''' as Tbl2 ,b.* from (Select ' + @Fld1 + ' from ' + @Tbl1
set @SQL = @SQL + ' EXCEPT SELECT ' + @Fld2 + ' from ' + @Tbl2 + ')s full join (Select ' + @Fld2 + ' from ' + @Tbl2
set @SQL = @SQL + ' EXCEPT SELECT ' + @Fld1 + ' from ' + @Tbl1 +')b on '+ @Pk

--Run SQL statement
Exec(@SQL)
END


답변

출처 : Lukas Eder의 SQL에서 두 테이블을 비교하려면 NATURAL FULL JOIN을 사용합니다 .

NATURAL FULL JOIN두 테이블간에 동일하거나 다른 행을 감지하는 데 사용 하는 영리한 접근 방식입니다 .

예 1-상태 플래그 :

SELECT t1.*, t2.*, CASE WHEN t1 IS NULL OR t2 IS NULL THEN 'Not equal' ELSE 'Equal' END
FROM t1
NATURAL FULL JOIN t2;

예 2-행 필터링

SELECT *
FROM (SELECT 't1' AS t1, t1.* FROM t1) t1
NATURAL FULL JOIN (SELECT 't2' AS t2, t2.* FROM t2) t2
WHERE t1 IS NULL OR t2 IS NULL -- show differences
--WHERE  t1 IS NOT NULL AND t2 IS NOT NULL    -- show the same

db <> 바이올린 데모