복붙노트

[SQL] 두 테이블 사이의 수익률 차이에 SQL 쿼리

SQL

두 테이블 사이의 수익률 차이에 SQL 쿼리

나는 일부 데이터를 확인하기 위해 두 개의 테이블, SQL Server를 비교하려합니다. 나는 데이터가 하나 또는 다른에 하나입니다 두 테이블의 모든 행을 반환하고자합니다. 본질적으로, 나는 모든 차이를 보여주고 싶어요. 그래서, 이름, 성 및 제품을하고 데이터의 세 가지를 확인해야합니다.

나는 SQL에 비교적 새로운 해요 그리고 내가 이상 일을 복잡하게되어 찾는거야 솔루션의 많은 것 같다. 나는 널 (NULL)에 대해 걱정할 필요가 없습니다.

나는 이런 식으로 뭔가를 시도하여 시작 :

SELECT DISTINCT [First Name], [Last Name], [Product Name] FROM [Temp Test Data]
WHERE ([First Name] NOT IN (SELECT [First Name] 
FROM [Real Data]))

나는 문제가이 더 생각을 복용하는 데 문제가 있습니다.

감사!

편집하다:

나는 다음과 같은 쿼리의 변형을 사용하려고 한 @treaschf로 답변에 따라 :

SELECT td.[First Name], td.[Last Name], td.[Product Name]
FROM [Temp Test Data] td FULL OUTER JOIN [Data] AS d 
ON td.[First Name] = d.[First Name] AND td.[Last Name] = d.[Last Name] 
WHERE (d.[First Name] = NULL) AND (d.[Last Name] = NULL)

그러나 나는 D에없는 TD 적어도 1 개 행이 있다는 것을 알게되면, 다시 0 결과를 얻는 유지한다.

편집하다:

좋아, 내가 그것을 알아 냈다고 생각합니다. 테스트 내 몇 분 적어도 충분한을 작동하는 것 같다.

SELECT [First Name], [Last Name]
FROM [Temp Test Data] AS td
WHERE (NOT EXISTS
        (SELECT [First Name], [Last Name]
         FROM [Data] AS d
         WHERE ([First Name] = td.[First Name]) OR ([Last Name] = td.[Last Name])))

이것은 기본적으로 내 실제 데이터가 아닌 내 테스트 데이터가 무엇인지 말해 줄 것입니다. 어느 내가 무엇을해야하는지에 대해 완전히 괜찮습니다.

해결법

  1. ==============================

    1.당신이 테이블 A와 B, 콜 럼의 C에 모두있는 경우, 여기에 테이블 A에서가 아니라 B에 존재하는 기록이다 :

    당신이 테이블 A와 B, 콜 럼의 C에 모두있는 경우, 여기에 테이블 A에서가 아니라 B에 존재하는 기록이다 :

    SELECT A.*
    FROM A
        LEFT JOIN B ON (A.C = B.C)
    WHERE B.C IS NULL
    

    단일 쿼리의 모든 차이를 얻으려면, 전체는 다음과 같이 사용해야합니다 조인 :

    SELECT A.*, B.*
    FROM A
        FULL JOIN B ON (A.C = B.C)
    WHERE A.C IS NULL OR B.C IS NULL
    

    당신이이 경우에 알 필요가있다, 그 기록은 발견 할 수있는 경우가 아닌 B에서 A의 B에서 온 열이 유사 B에 존재하는 사람들을위한하지 NULL, 그리고 것보다 , A로부터 열이 null이됩니다.

  2. ==============================

    2.

    (   SELECT * FROM table1
        EXCEPT
        SELECT * FROM table2)  
    UNION ALL
    (   SELECT * FROM table2
        EXCEPT
        SELECT * FROM table1) 
    
  3. ==============================

    3.나는이 인기가 해답이 될 수 없습니다 것을 알고 있지만 좀 더 복잡한 비교가 필요한 경우 타사 도구를 사용하여 @Randy 마인더에 동의 않습니다.

    나는이 인기가 해답이 될 수 없습니다 것을 알고 있지만 좀 더 복잡한 비교가 필요한 경우 타사 도구를 사용하여 @Randy 마인더에 동의 않습니다.

    여기이 특정 케이스는 쉽고 같은 도구가 필요하지 않습니다이 경우입니다하지만 당신은 두 개의 서버, 더 복잡한 비교 기준 등에 더 많은 열, 데이터베이스를 소개하는 경우이 쉽게 복잡한 얻을 수 있습니다.

    이 같은 ApexSQL 데이터 DIFF 또는 퀘스트 두꺼비 이러한 도구 많이 있습니다 그리고 당신은 항상 작업을 완수하기 위해 시험 모드로 사용할 수 있습니다.

  4. ==============================

    4.두 테이블 사이의 모든 차이를 얻으려면, 당신은 나처럼이 SQL 요청을 사용할 수 있습니다 :

    두 테이블 사이의 모든 차이를 얻으려면, 당신은 나처럼이 SQL 요청을 사용할 수 있습니다 :

    SELECT 'TABLE1-ONLY' AS SRC, T1.*
    FROM (
          SELECT * FROM Table1
          EXCEPT
          SELECT * FROM Table2
          ) AS T1
    UNION ALL
    SELECT 'TABLE2-ONLY' AS SRC, T2.*
    FROM (
          SELECT * FROM Table2
          EXCEPT
          SELECT * FROM Table1
          ) AS T2
    ;
    
  5. ==============================

    5.쇼하는 테이블 행에 있는지 @erikkallen 대답에 간단한 변화 :

    쇼하는 테이블 행에 있는지 @erikkallen 대답에 간단한 변화 :

    (   SELECT 'table1' as source, * FROM table1
        EXCEPT
        SELECT * FROM table2)  
    UNION ALL
    (   SELECT 'table2' as source, * FROM table2
        EXCEPT
        SELECT * FROM table1) 
    

    당신은 오류가 발생하는 경우

    다음은 추가하는 데 도움이 될 수 있습니다

    (   SELECT 'table1' as source, * FROM table1
        EXCEPT
        SELECT 'table1' as source, * FROM table2)  
    UNION ALL
    (   SELECT 'table2' as source, * FROM table2
        EXCEPT
        SELECT 'table2' as source, * FROM table1) 
    
  6. ==============================

    6.당신이 열 값이 다른 어떤 얻고 싶은 경우에, 당신은 엔티티 - 속성 - 값 모델을 사용할 수 있습니다 :

    당신이 열 값이 다른 어떤 얻고 싶은 경우에, 당신은 엔티티 - 속성 - 값 모델을 사용할 수 있습니다 :

    declare @Data1 xml, @Data2 xml
    
    select @Data1 = 
    (
        select * 
        from (select * from Test1 except select * from Test2) as a
        for xml raw('Data')
    )
    
    select @Data2 = 
    (
        select * 
        from (select * from Test2 except select * from Test1) as a
        for xml raw('Data')
    )
    
    ;with CTE1 as (
        select
            T.C.value('../@ID', 'bigint') as ID,
            T.C.value('local-name(.)', 'nvarchar(128)') as Name,
            T.C.value('.', 'nvarchar(max)') as Value
        from @Data1.nodes('Data/@*') as T(C)    
    ), CTE2 as (
        select
            T.C.value('../@ID', 'bigint') as ID,
            T.C.value('local-name(.)', 'nvarchar(128)') as Name,
            T.C.value('.', 'nvarchar(max)') as Value
        from @Data2.nodes('Data/@*') as T(C)     
    )
    select
        isnull(C1.ID, C2.ID) as ID, isnull(C1.Name, C2.Name) as Name, C1.Value as Value1, C2.Value as Value2
    from CTE1 as C1
        full outer join CTE2 as C2 on C2.ID = C1.ID and C2.Name = C1.Name
    where
    not
    (
        C1.Value is null and C2.Value is null or
        C1.Value is not null and C2.Value is not null and C1.Value = C2.Value
    )
    

    SQL 뿐인 예

  7. ==============================

    7.이 시도 :

    이 시도 :

    SELECT 
        [First Name], [Last Name]
    FROM 
        [Temp Test Data] AS td EXCEPTION JOIN [Data] AS d ON 
             (d.[First Name] = td.[First Name] OR d.[Last Name] = td.[Last Name])
    

    읽기가 훨씬 간단합니다.

  8. ==============================

    8.이 티아구의 솔루션, 반환 "소스"테이블 비슷한 트릭을뿐만 아니라 할 것입니다.

    이 티아구의 솔루션, 반환 "소스"테이블 비슷한 트릭을뿐만 아니라 할 것입니다.

    select [First name], [Last name], max(_tabloc) as _tabloc
    from (
      select [First Name], [Last name], 't1' as _tabloc from table1
      union all
      select [First name], [Last name], 't2' as _tabloc from table2
    ) v
    group by [Fist Name], [Last name]
    having count(1)=1
    

    당신이 테이블 참조를해야합니다 _tabloc 결과는 열의 테이블 사이의 차이를, 포함됩니다.

  9. ==============================

    9.이 같은 예를 들어 뭔가를 제외하고 사용할 수 있습니다 :

    이 같은 예를 들어 뭔가를 제외하고 사용할 수 있습니다 :

    -- DB1..Tb1 have values than DB2..Tb1 not have
    Select Col1,Col2,Col3 From DB1..Tb1
    except
    Select Col1,Col2,Col3 From DB2..Tb1
    -- Now we change order
    -- DB2..Tb1 have values than DB1..Tb1 not have
    Select Col1,Col2,Col3 From DB2..Tb1
    except
    Select Col1,Col2,Col3 From DB1..Tb1
    
  10. ==============================

    10.당신이 열 이름에 대한 걱정에서 두 개의 테이블 / w를 일치하기 위해 노력하고 간단한 연기 테스트의 경우 :

    당신이 열 이름에 대한 걱정에서 두 개의 테이블 / w를 일치하기 위해 노력하고 간단한 연기 테스트의 경우 :

    --ensure tables have matching records
    Select count (*) from tbl_A
    Select count (*) from tbl_B
    
    --create temp table of all records in both tables
    Select * into #demo from tbl_A 
    Union All
    Select * from tbl_B
    
    --Distinct #demo records = Total #demo records/2 = Total tbl_A records = total tbl_B records
    Select distinct * from #demo 
    

    당신은 쉽게 테이블의 배치를 비교하기 위해 저장 프로 시저를 작성 할 수 있습니다.

  11. ==============================

    11.SP에 같은 차이점의 캐딜락을 제시. @erikkallen 의해 답변을 기반으로 한 기본 템플릿에서 참조하십시오. 그것은 지원

    SP에 같은 차이점의 캐딜락을 제시. @erikkallen 의해 답변을 기반으로 한 기본 템플릿에서 참조하십시오. 그것은 지원

    exec Common.usp_DiffTableRows '#t1', '#t2';
    
    exec Common.usp_DiffTableRows 
        @pTable0          = 'ydb.ysh.table1',
        @pTable1          = 'xdb.xsh.table2',
        @pOrderByCsvOpt   = null,  -- Order the results
        @pOnlyCsvOpt      = null,  -- Only compare these columns
        @pIgnoreCsvOpt    = null;  -- Ignore these columns (ignored if @pOnlyCsvOpt is specified)
    
    alter proc [Common].[usp_DiffTableRows]    
        @pTable0          varchar(300),
        @pTable1          varchar(300),
        @pOrderByCsvOpt   nvarchar(1000) = null,  -- Order the Results
        @pOnlyCsvOpt      nvarchar(4000) = null,  -- Only compare these columns
        @pIgnoreCsvOpt    nvarchar(4000) = null,  -- Ignore these columns (ignored if @pOnlyCsvOpt is specified)
        @pDebug           bit = 0
    as
    /*---------------------------------------------------------------------------------------------------------------------
        Purpose:  Compare rows between two tables.
    
          Usage:  exec Common.usp_DiffTableRows '#a', '#b';
    
        Modified    By          Description
        ----------  ----------  -------------------------------------------------------------------------------------------
        2015.10.06  crokusek    Initial Version
        2019.03.13  crokusek    Added @pOrderByCsvOpt
        2019.06.26  crokusek    Support for @pIgnoreCsvOpt, @pOnlyCsvOpt.    
        2019.09.04  crokusek    Minor debugging improvement
        2020.03.12  crokusek    Detect duplicate rows in either source table
      ---------------------------------------------------------------------------------------------------------------------*/
    begin try
    
        if (substring(@pTable0, 1, 1) = '#')
            set @pTable0 = 'tempdb..' + @pTable0; -- object_id test below needs full names for temp tables
    
        if (substring(@pTable1, 1, 1) = '#')
            set @pTable1 = 'tempdb..' + @pTable1; -- object_id test below needs full names for temp tables
    
        if (object_id(@pTable0) is null)
            raiserror('Table name is not recognized: ''%s''', 16, 1, @pTable0);
    
        if (object_id(@pTable1) is null)
            raiserror('Table name is not recognized: ''%s''', 16, 1, @pTable1);
    
        create table #ColumnGathering
        (
            Name nvarchar(300) not null,
            Sequence int not null,
            TableArg tinyint not null
        );
    
        declare
            @usp          varchar(100) = object_name(@@procid),    
            @sql          nvarchar(4000),
            @sqlTemplate  nvarchar(4000) = 
            '  
                use $database$;
    
                insert into #ColumnGathering
                select Name, column_id as Sequence, $TableArg$ as TableArg
                  from sys.columns c
                 where object_id = object_id(''$table$'', ''U'')
            ';          
    
        set @sql = replace(replace(replace(@sqlTemplate,
            '$TableArg$', 0),
            '$database$', (select DatabaseName from Common.ufn_SplitDbIdentifier(@pTable0))),
            '$table$', @pTable0);
    
        if (@pDebug = 1)
            print 'Sql #CG 0: ' + @sql;
    
        exec sp_executesql @sql;
    
        set @sql = replace(replace(replace(@sqlTemplate,
            '$TableArg$', 1),
            '$database$', (select DatabaseName from Common.ufn_SplitDbIdentifier(@pTable1))),
            '$table$', @pTable1);
    
        if (@pDebug = 1)
            print 'Sql #CG 1: ' + @sql;
    
        exec sp_executesql @sql;
    
        if (@pDebug = 1)
            select * from #ColumnGathering;
    
        select Name, 
               min(Sequence) as Sequence, 
               convert(bit, iif(min(TableArg) = 0, 1, 0)) as InTable0,
               convert(bit, iif(max(TableArg) = 1, 1, 0)) as InTable1
          into #Columns
          from #ColumnGathering
         group by Name
        having (     @pOnlyCsvOpt is not null 
                 and Name in (select Value from Common.ufn_UsvToNVarcharKeyTable(@pOnlyCsvOpt, default)))
            or 
               (     @pOnlyCsvOpt is null
                 and @pIgnoreCsvOpt is not null 
                 and Name not in (select Value from Common.ufn_UsvToNVarcharKeyTable(@pIgnoreCsvOpt, default)))
            or 
               (     @pOnlyCsvOpt is null
                 and @pIgnoreCsvOpt is null)
    
        if (exists (select 1 from #Columns where InTable0 = 0 or InTable1 = 0))
        begin
            select 1; -- without this the debugging info doesn't stream sometimes
            select * from #Columns order by Sequence;        
            waitfor delay '00:00:02';  -- give results chance to stream before raising exception
            raiserror('Columns are not equal between tables, consider using args @pIgnoreCsvOpt, @pOnlyCsvOpt.  See Result Sets for details.', 16, 1);    
        end
    
        if (@pDebug = 1)
            select * from #Columns order by Sequence;
    
        declare 
            @columns nvarchar(4000) = --iif(@pOnlyCsvOpt is null and @pIgnoreCsvOpt is null,
               -- '*',     
                (
                  select substring((select ',' + ac.name
                    from #Columns ac
                   order by Sequence
                     for xml path('')),2,200000) as csv
                );
    
        if (@pDebug = 1)
        begin
            print 'Columns: ' + @columns;
            waitfor delay '00:00:02';  -- give results chance to stream before possibly raising exception
        end
    
        -- Based on https://stackoverflow.com/a/2077929/538763
        --     - Added sensing for duplicate rows
        --     - Added reporting of source table location
        --
        set @sqlTemplate = '
                with 
                   a as (select ~, Row_Number() over (partition by ~ order by (select null)) -1 as Duplicates from $a$), 
                   b as (select ~, Row_Number() over (partition by ~ order by (select null)) -1 as Duplicates from $b$)
                select 0 as SourceTable, ~
                  from 
                     (
                       select * from a
                       except
                       select * from b
                     )  anb
                  union all
                 select 1 as SourceTable, ~
                   from 
                     (
                       select * from b
                       except
                       select * from a
                     )  bna
                 order by $orderBy$
            ';    
    
         set @sql = replace(replace(replace(replace(@sqlTemplate, 
                '$a$', @pTable0), 
                '$b$', @pTable1),
                '~', @columns),
                '$orderBy$', coalesce(@pOrderByCsvOpt, @columns + ', SourceTable')
            );
    
         if (@pDebug = 1)
            print 'Sql: ' + @sql;
    
         exec sp_executesql @sql;
    
    end try
    begin catch
        declare        
            @CatchingUsp  varchar(100) = object_name(@@procid);    
    
        if (xact_state() = -1)
            rollback;    
    
        -- Disabled for S.O. post
    
        --exec Common.usp_Log
            --@pMethod = @CatchingUsp;
    
        --exec Common.usp_RethrowError        
            --@pCatchingMethod = @CatchingUsp;
    
        throw;
    end catch
    go
    
    create function Common.Trim
    (
        @pOriginalString nvarchar(max), 
        @pCharsToTrim nvarchar(50) = null -- specify null or 'default' for whitespae 
    )  
    returns table
    with schemabinding
    as 
    /*--------------------------------------------------------------------------------------------------
        Purpose:   Trim the specified characters from a string.
    
        Modified    By              Description
        ----------  --------------  --------------------------------------------------------------------
        2012.09.25  S.Rutszy/crok   Modified from https://dba.stackexchange.com/a/133044/9415    
      --------------------------------------------------------------------------------------------------*/ 
    return
    with cte AS
    (
      select patindex(N'%[^' + EffCharsToTrim + N']%', @pOriginalString) AS [FirstChar],
             patindex(N'%[^' + EffCharsToTrim + N']%', reverse(@pOriginalString)) AS [LastChar],
             len(@pOriginalString + N'~') - 1 AS [ActualLength]
       from
       (
             select EffCharsToTrim = coalesce(@pCharsToTrim, nchar(0x09) + nchar(0x20) + nchar(0x0d) + nchar(0x0a))
       ) c
    )
    select substring(@pOriginalString, [FirstChar],
                     ((cte.[ActualLength] - [LastChar]) - [FirstChar] + 2)
           ) AS [TrimmedString]
           --
           --cte.[ActualLength],
           --[FirstChar],
           --((cte.[ActualLength] - [LastChar]) + 1) AS [LastChar]              
    from cte;
    go
    
    create function [Common].[ufn_UsvToNVarcharKeyTable] (
        @pCsvList     nvarchar(MAX),
        @pSeparator   nvarchar(1) = ','       -- can pass keyword 'default' when calling using ()'s
        )    
        --
        -- SQL Server 2012 distinguishes nvarchar keys up to maximum of 450 in length (900 bytes)
        -- 
        returns @tbl table (Value nvarchar(450) not null primary key(Value)) as
    /*-------------------------------------------------------------------------------------------------
        Purpose:  Converts a comma separated list of strings into a sql NVarchar table.  From
    
                  http://www.programmingado.net/a-398/SQL-Server-parsing-CSV-into-table.aspx     
    
                  This may be called from RunSelectQuery:
    
                      GRANT SELECT ON Common.ufn_UsvToNVarcharTable TO MachCloudDynamicSql;
    
        Modified    By              Description
        ----------  --------------  -------------------------------------------------------------------
        2011.07.13  internet        Initial version
        2011.11.22  crokusek        Support nvarchar strings and a custom separator.
        2017.12.06  crokusek        Trim leading and trailing whitespace from each element.
        2019.01.26  crokusek        Remove newlines
      -------------------------------------------------------------------------------------------------*/     
    begin
        declare 
            @pos      int,
            @textpos  int,
            @chunklen smallint,
            @str      nvarchar(4000),
            @tmpstr   nvarchar(4000),
            @leftover nvarchar(4000),
            @csvList nvarchar(max) = iif(@pSeparator not in (char(13), char(10), char(13) + char(10)),
                replace(replace(@pCsvList, char(13), ''), char(10), ''),
                @pCsvList); -- remove newlines
    
        set @textpos = 1
        set @leftover = ''  
        while @textpos <= len(@csvList)
        begin
            set @chunklen = 4000 - len(@leftover)
            set @tmpstr = ltrim(@leftover + substring(@csvList, @textpos, @chunklen))
            set @textpos = @textpos + @chunklen
    
            set @pos = charindex(@pSeparator, @tmpstr)
            while @pos > 0
            begin
                set @str = substring(@tmpstr, 1, @pos - 1)
                set @str = (select TrimmedString from Common.Trim(@str, default));
                insert @tbl (value) values(@str);
                set @tmpstr = ltrim(substring(@tmpstr, @pos + 1, len(@tmpstr)))
                set @pos = charindex(@pSeparator, @tmpstr)
            end
    
            set @leftover = @tmpstr
        end
    
        -- Handle @leftover
    
        set @str = (select TrimmedString from Common.Trim(@leftover, default));
    
        if @str <> ''
           insert @tbl (value) values(@str);
    
        return
    end
    GO
    
    create function Common.ufn_SplitDbIdentifier(@pIdentifier nvarchar(300))
    returns @table table 
    (    
        InstanceName          nvarchar(300) not null,
        DatabaseName          nvarchar(300) not null,
        SchemaName            nvarchar(300),
        BaseName              nvarchar(300) not null,
        FullTempDbBaseName    nvarchar(300),            -- non-null for tempdb (e.g. #Abc____...)
        InstanceWasSpecified  bit not null,
        DatabaseWasSpecified  bit not null,
        SchemaWasSpecified    bit not null,
        IsCurrentInstance     bit not null,
        IsCurrentDatabase     bit not null,
        IsTempDb              bit not null,
        OrgIdentifier         nvarchar(300) not null
    ) as
    /*-----------------------------------------------------------------------------------------------------------
        Purpose:  Split a Sql Server Identifier into its parts, providing appropriate default values and
                  handling temp table (tempdb) references.
    
        Example:  select * from Common.ufn_SplitDbIdentifier('t')
                  union all
                  select * from Common.ufn_SplitDbIdentifier('s.t')
                  union all
                  select * from Common.ufn_SplitDbIdentifier('d.s.t')
                  union all
                  select * from Common.ufn_SplitDbIdentifier('i.d.s.t')
                  union all
                  select * from Common.ufn_SplitDbIdentifier('#d')
                  union all
                  select * from Common.ufn_SplitDbIdentifier('tempdb..#d'); 
    
                  -- Empty
                  select * from Common.ufn_SplitDbIdentifier('illegal name'); 
    
        Modified    By              Description
        ----------  --------------  -----------------------------------------------------------------------------
        2013.09.27  crokusek        Initial version.  
      -----------------------------------------------------------------------------------------------------------*/
    begin
        declare 
            @name nvarchar(300) = ltrim(rtrim(@pIdentifier));
    
        -- Return an empty table as a "throw"
        --
        --Removed for SO post
        --if (Common.ufn_IsSpacelessLiteralIdentifier(@name) = 0)
          --  return;
    
        -- Find dots starting from the right by reversing first.
    
        declare 
            @revName nvarchar(300) = reverse(@name);
    
        declare
            @firstDot int = charindex('.', @revName);
    
        declare
            @secondDot  int = iif(@firstDot = 0,  0, charindex('.', @revName, @firstDot + 1));
    
        declare
            @thirdDot   int = iif(@secondDot = 0, 0, charindex('.', @revName, @secondDot + 1));
    
        declare
            @fourthDot  int = iif(@thirdDot = 0, 0, charindex('.', @revName, @thirdDot + 1));
    
        --select @firstDot, @secondDot, @thirdDot, @fourthDot, len(@name);
    
        -- Undo the reverse() (first dot is first from the right).
        --
        set @firstDot = iif(@firstDot = 0, 0, len(@name) - @firstDot + 1);
        set @secondDot = iif(@secondDot = 0, 0, len(@name) - @secondDot + 1);
        set @thirdDot = iif(@thirdDot = 0, 0, len(@name) - @thirdDot + 1);
        set @fourthDot = iif(@fourthDot = 0, 0, len(@name) - @fourthDot + 1);
    
        --select @firstDot, @secondDot, @thirdDot, @fourthDot, len(@name);
    
        declare
            @baseName   nvarchar(300)  = substring(@name, @firstDot + 1, len(@name) - @firstdot);
    
        declare
            @schemaName nvarchar(300) = iif(@firstDot - @secondDot - 1 <= 0, 
                                            null,
                                            substring(@name, @secondDot + 1, @firstDot - @secondDot - 1));
        declare
            @dbName     nvarchar(300) = iif(@secondDot - @thirdDot - 1 <= 0, 
                                            null,
                                            substring(@name, @thirdDot + 1, @secondDot - @thirdDot - 1));
        declare
            @instName   nvarchar(300) = iif(@thirdDot - @fourthDot - 1 <= 0, 
                                            null, 
                                            substring(@name, @fourthDot + 1, @thirdDot - @fourthDot - 1));
    
        with input as (
            select
               coalesce(@instName, '[' + @@servername + ']') as InstanceName,
               coalesce(@dbName,     iif(left(@baseName, 1) = '#', 'tempdb', db_name())) as DatabaseName,
               coalesce(@schemaName, iif(left(@baseName, 1) = '#', 'dbo', schema_name())) as SchemaName,
               @baseName as BaseName,
               iif(left(@baseName, 1) = '#',
                   (
                      select [name] from tempdb.sys.objects
                      where object_id = object_id('tempdb..' + @baseName)
                   ), 
                   null) as FullTempDbBaseName,                
               iif(@instName is null, 0, 1) InstanceWasSpecified,       
               iif(@dbName is null, 0, 1) DatabaseWasSpecified,
               iif(@schemaName is null, 0, 1) SchemaWasSpecified    
         )
         insert into @table           
         select i.InstanceName, i.DatabaseName, i.SchemaName, i.BaseName, i.FullTempDbBaseName,
                i.InstanceWasSpecified, i.DatabaseWasSpecified, i.SchemaWasSpecified,
                iif(i.InstanceName = '[' + @@servername + ']', 1, 0) as IsCurrentInstance,
                iif(i.DatabaseName = db_name(), 1, 0) as IsCurrentDatabase,
                iif(left(@baseName, 1) = '#', 1, 0) as IsTempDb,
                @name as OrgIdentifier
           from input i;
    
        return;
    end
    GO
    
  12. ==============================

    12.뿐만 아니라 전체 대량의 데이터와 조인 왼쪽과 관련된 성능 문제가 있습니다.

    뿐만 아니라 전체 대량의 데이터와 조인 왼쪽과 관련된 성능 문제가 있습니다.

    내 생각에 이것은 최선의 솔루션입니다 :

    select [First Name], count(1) e from (select * from [Temp Test Data] union all select * from [Temp Test Data 2]) a group by [First Name] having e = 1
    
  13. from https://stackoverflow.com/questions/2077807/sql-query-to-return-differences-between-two-tables by cc-by-sa and MIT license