如果任何列与另一个表中的匹配行不同,如何插入行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果任何列与另一个表中的匹配行不同,如何插入行相关的知识,希望对你有一定的参考价值。

基本上我在我们的网络上提取计算机列表。我想在我的临时表#general中比较我的ADScanGeneral表中特定计算机名称XXXX-XXXX-XXXXX的信息。基本上我想将#general的计算机条目列与ADScanGeneral中的最新条目进行比较,如果它们在任何地方不同,则将#general中的行输入ADScanGeneral作为新条目。否则,如果它们相同,则只需更新该计算机的ADScanGeneral.EntryDate列。

我的问题是我想不出一种方法来比较#general和ADScanGeneral中单个条目的列,而不需要做很长的循环。这在SQL语句中是否可行?

我的表格的例子如下:

“#一般”

Name    Status  lastLogon   LastLogonDate   lastLogonTimestamp  ResolvedIP  Manufacturer    Model   Architecture    TotalPhysicalMemory LastLoggedOnUser    WakeUpType  OperatingSystem OperatingSystemVersion  OperatingSystemArchitecture SystemDrive SerialNumber    SMBiosBIOSVersion   BIOSVersion CPUName CPUCaption  MaxClockSpeed   LastClockSpeed  NumberOfProcessors  NumberOfCores   NumberOfThreads
XXXX-XXXX-10362 1   2018-02-01 06:37:18 2018-01-27 22:37:03 2018-01-27 22:37:03 10.1.19.7   Dell Inc.   OptiPlex 390    x64-based PC    8481869824  XXXXX\amanda.creathbaum 6   Microsoft Windows 10 Pro    10.1.7601   64-bit  C:  G6WLTR1 A01 DELL   - 6222004    Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz Intel64 Family 6 Model 42 Stepping 7    3101    1581    1   4   4
XXXX-XXXX-10947 0   2018-02-01 06:29:57 2018-02-01 02:09:54 2018-02-01 02:09:54 10.1.19.4                                                                               
XXXX-XXXX-01738 0   2018-02-01 17:58:37 2017-11-13 17:58:37 2017-11-13 17:58:37                                                                                 

“ADScanGeneral”

Name    Status  lastLogon   LastLogonDate   lastLogonTimestamp  ResolvedIP  Manufacturer    Model   Architecture    TotalPhysicalMemory LastLoggedOnUser    WakeUpType  OperatingSystem OperatingSystemVersion  OperatingSystemArchitecture SystemDrive SerialNumber    SMBIOSBIOSVersion   BIOSVersion CPUName CPUCaption  MaxClockSpeed   LastClockSpeed  NumberOfProcessors  NumberOfCores   NumberOfThreads    EntryDate
XXXX-XXXX-10362 1   2018-02-01 06:37:18 2018-01-27 22:37:03 2018-01-27 22:37:03 10.1.19.7   Dell Inc.   OptiPlex 390    x64-based PC    8481869824  XXXXX\amanda.creathbaum 6   Microsoft Windows 7 Professional    6.1.7601    64-bit  C:  G6WLTR1 A01 DELL   - 6222004    Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz Intel64 Family 6 Model 42 Stepping 7    3101    1581    1   4   4    2018-02-01 06:37:18
XXXX-XXXX-10947 0   2018-02-01 06:29:57 2018-02-01 02:09:54 2018-02-01 02:09:54 10.1.19.4                                                                               2018-02-01 06:37:18
XXXX-XXXX-01738 0   2017-11-13 17:58:37 2017-11-13 17:58:37 2017-11-13 17:58:37                                                                                 2018-02-01 06:37:18

因此,对于第一个条目,操作系统已更改为Windows 10,因此我希望将整个条目作为新条目插入到ADScanGeneral中。第二个条目,没有任何改变,所以我想更新ADScanGeneral中的输入日期。第三个条目有一个更新的lastLogon,所以我想将它作为一个新的条目添加到ADScanGeneral中。

那有意义吗?如果您需要澄清,请询问,我会尽力帮助您。谢谢大家的帮助!

JoeC建议检查合并命令,但它似乎只匹配您在ON条件中指定的2个字段,而我需要它匹配整个行。所以我不确定我是不是错误地使用了命令,或者它是否对我不起作用。这是我提出的合并命令:

MERGE   ADScanGeneral   AS TARGET
USING   #General        AS SOURCE
ON      (TARGET.[Name] = SOURCE.[Name])
WHEN MATCHED THEN
        UPDATE SET EntryDate = getdate()
WHEN NOT MATCHED THEN
        INSERT  (
                    [Name], 
                    [Status], 
                    LastLogon, 
                    LastLogonDate, 
                    LastLogonTimestamp,
                    ResolvedIP, 
                    Manufacturer, 
                    Model, 
                    Architecture, 
                    TotalPhysicalMemory, 
                    LastLoggedOnUser,
                    WakeUpType,
                    OperatingSystem,
                    OperatingSystemVersion,
                    OperatingSystemArchitecture,
                    SystemDirectory,
                    SerialNumber,
                    SMBIOSVersion,
                    BIOSVersion,
                    CPUName,
                    CPUCaption,
                    MaxClockSpeed,
                    NumberOfProcessors,
                    NumberOfThreads,
                    NumberOfCores
                )
        VALUES  (
                    SOURCE.[Name], 
                    SOURCE.[Status], 
                    SOURCE.LastLogon, 
                    SOURCE.LastLogonDate, 
                    SOURCE.LastLogonTimestamp,
                    SOURCE.ResolvedIP, 
                    SOURCE.Manufacturer, 
                    SOURCE.Model, 
                    SOURCE.Architecture, 
                    SOURCE.TotalPhysicalMemory, 
                    SOURCE.LastLoggedOnUser,
                    SOURCE.WakeUpType,
                    SOURCE.OperatingSystem,
                    SOURCE.OperatingSystemVersion,
                    SOURCE.OperatingSystemArchitecture,
                    SOURCE.SystemDirectory,
                    SOURCE.SerialNumber,
                    SOURCE.SMBIOSVersion,
                    SOURCE.BIOSVersion,
                    SOURCE.CPUName,
                    SOURCE.CPUCaption,
                    SOURCE.MaxClockSpeed,
                    SOURCE.NumberOfProcessors,
                    SOURCE.NumberOfCores,
                    SOURCE.NumberOfThreads
                );
答案

实现此目的的一种方法是使用output clause跟踪已插入的名称,并在筛选后在第二个查询中执行更新以删除插入的名称。

可能有更好的方法来检查更改,但下面的代码应该可行。

declare @inserted_names table ([Name] varchar(255));

-- insert into ADScanGeneral any records from #general with changes, or any
-- name that is not present in ADScanGeneral
-- the names of the inserted record are stored to a table variable
insert into ADScanGeneral
output inserted.[Name] into @inserted_names ([Name])
select
    c.*, GetDate() as EntryDate
from
    ADScanGeneral as a
inner join
    (
        select
            a.[Name], max(a.EntryDate) as MaxEntryDate
        from
            ADScanGeneral as a
        group by
            a.[Name]
    ) as b
    on
        a.[Name] = b.[Name]
        and
        a.EntryDate = b.MaxEntryDate
right join
    #general as c
    on
        (a.[Name] = c.[Name] or a.[Name] is null)
        and
        (
            (a.[Status] <> c.[Status] or (a.[Status] is null and c.[Status] is not null) or (a.[Status] is not null and c.[Status] is null))
            or (a.[lastLogon] <> c.[lastLogon] or (a.[lastLogon] is null and c.[lastLogon] is not null) or (a.[lastLogon] is not null and c.[lastLogon] is null))
            or (a.[LastLogonDate] <> c.[LastLogonDate] or (a.[LastLogonDate] is null and c.[LastLogonDate] is not null) or (a.[LastLogonDate] is not null and c.[LastLogonDate] is null))
            or (a.[lastLogonTimestamp] <> c.[lastLogonTimestamp] or (a.[lastLogonTimestamp] is null and c.[lastLogonTimestamp] is not null) or (a.[lastLogonTimestamp] is not null and c.[lastLogonTimestamp] is null))
            or (a.[ResolvedIP] <> c.[ResolvedIP] or (a.[ResolvedIP] is null and c.[ResolvedIP] is not null) or (a.[ResolvedIP] is not null and c.[ResolvedIP] is null))
            or (a.[Manufacturer] <> c.[Manufacturer] or (a.[Manufacturer] is null and c.[Manufacturer] is not null) or (a.[Manufacturer] is not null and c.[Manufacturer] is null))
            or (a.[Model] <> c.[Model] or (a.[Model] is null and c.[Model] is not null) or (a.[Model] is not null and c.[Model] is null))
            or (a.[Architecture] <> c.[Architecture] or (a.[Architecture] is null and c.[Architecture] is not null) or (a.[Architecture] is not null and c.[Architecture] is null))
            (a.[TotalPhysicalMemory] <> c.[TotalPhysicalMemory] or (a.[TotalPhysicalMemory] is null and c.[TotalPhysicalMemory] is not null) or (a.[TotalPhysicalMemory] is not null and c.[TotalPhysicalMemory] is null))
            or (a.[LastLoggedOnUser] <> c.[LastLoggedOnUser] or (a.[LastLoggedOnUser] is null and c.[LastLoggedOnUser] is not null) or (a.[LastLoggedOnUser] is not null and c.[LastLoggedOnUser] is null))
            or (a.[WakeUpType] <> c.[WakeUpType] or (a.[WakeUpType] is null and c.[WakeUpType] is not null) or (a.[WakeUpType] is not null and c.[WakeUpType] is null))
            or (a.[OperatingSystem] <> c.[OperatingSystem] or (a.[OperatingSystem] is null and c.[OperatingSystem] is not null) or (a.[OperatingSystem] is not null and c.[OperatingSystem] is null))
            or (a.[OperatingSystemVersion] <> c.[OperatingSystemVersion] or (a.[OperatingSystemVersion] is null and c.[OperatingSystemVersion] is not null) or (a.[OperatingSystemVersion] is not null and c.[OperatingSystemVersion] is null))
            or (a.[OperatingSystemArchitecture] <> c.[OperatingSystemArchitecture] or (a.[OperatingSystemArchitecture] is null and c.[OperatingSystemArchitecture] is not null) or (a.[OperatingSystemArchitecture] is not null and c.[OperatingSystemArchitecture] is null))
            or (a.[SystemDrive] <> c.[SystemDrive] or (a.[SystemDrive] is null and c.[SystemDrive] is not null) or (a.[SystemDrive] is not null and c.[SystemDrive] is null))
            or (a.[SerialNumber] <> c.[SerialNumber] or (a.[SerialNumber] is null and c.[SerialNumber] is not null) or (a.[SerialNumber] is not null and c.[SerialNumber] is null))
            or (a.[SMBIOSBIOSVersion] <> c.[SMBIOSBIOSVersion] or (a.[SMBIOSBIOSVersion] is null and c.[SMBIOSBIOSVersion] is not null) or (a.[SMBIOSBIOSVersion] is not null and c.[SMBIOSBIOSVersion] is null))
            or (a.[BIOSVersion] <> c.[BIOSVersion] or (a.[BIOSVersion] is null and c.[BIOSVersion] is not null) or (a.[BIOSVersion] is not null and c.[BIOSVersion] is null))
            or (a.[CPUName] <> c.[CPUName] or (a.[CPUName] is null and c.[CPUName] is not null) or (a.[CPUName] is not null and c.[CPUName] is null))
            or (a.[CPUCaption] <> c.[CPUCaption] or (a.[CPUCaption] is null and c.[CPUCaption] is not null) or (a.[CPUCaption] is not null and c.[CPUCaption] is null))
            or (a.[MaxClockSpeed] <> c.[MaxClockSpeed] or (a.[MaxClockSpeed] is null and c.[MaxClockSpeed] is not null) or (a.[MaxClockSpeed] is not null and c.[MaxClockSpeed] is null))
            or (a.[LastClockSpeed] <> c.[LastClockSpeed] or (a.[LastClockSpeed] is null and c.[LastClockSpeed] is not null) or (a.[LastClockSpeed] is not null and c.[LastClockSpeed] is null))
            or (a.[NumberOfProcessors] <> c.[NumberOfProcessors] or (a.[NumberOfProcessors] is null and c.[NumberOfProcessors] is not null) or (a.[NumberOfProcessors] is not null and c.[NumberOfProcessors] is null))
            or (a.[NumberOfCores] <> c.[NumberOfCores] or (a.[NumberOfCores] is null and c.[NumberOfCores] is not null) or (a.[NumberOfCores] is not null and c.[NumberOfCores] is null))
            or (a.[NumberOfThreads] <> c.[NumberOfThreads] or (a.[NumberOfThreads] is null and c.[NumberOfThreads] is not null) or (a.[NumberOfThreads] is not null and c.[NumberOfThreads] is null))
        )



-- udate the records in ADScanGeneral for any names that were not inserted
-- during the previous step
update a
set
    a.EntryDate = getdate()
from
    ADScanGeneral as a
inner join
    (
        select
            a.[Name], max(a.EntryDate) as MaxEntryDate
        from
            ADScanGeneral as a
        group by
            a.[Name]
    ) as b
    on
        a.[Name] = b.[Name]
        and
        a.EntryDate = b.MaxEntryDate
inner join
    #general as c
    on
        a.[Name] = c.[Name]
left join
    @inserted_names as d
    on
        a.[Name] = d.[Name]
where
    d.[Name] is null

以上是关于如果任何列与另一个表中的匹配行不同,如何插入行的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server:交叉引用一个表中的多个列与另一个表中的多个列

将第一个文件的第一列与第二个文件中的行匹配,然后将第二个文件中匹配行的最后一列插入第一个文件中的新第一列

如何删除与另一个文档中的行匹配的行

当行悬停并且列值与另一行匹配时显示工具提示

允许一列与另一个表中的多行相关[重复]

如果列值 id 与另一个表中的 ID 描述匹配,则在指定列中插入数据(规范化形式)