Query to select records that do not appear in DB

2019-08-18 22:25发布

I am trying to add missing data to the DB and am therefore trying to collect this missing data through queries.

In my excel sheet I have two columns: col A is populated with component codes, while col J holds its respective asset type codes.

I want to find all non-existing component-asset type combinations in one query.

Currently, I am looping through the excel sheet like in the following example:

arr = Range("B3:J5000")
For i = 1 To 5000-2
    Set rs = cnn.Execute("Select Top 1 AT.Code From astComponents C Join astAssetTypes AT ON AT.Id = C.AssetTypeId Where C.Code = '" & arr(i, 1) & "' And AT.Code = '" & arr(i, 9) & "'")
    If rs.EOF Then
        'Missing data was found
    End If
Next i

This is however not to my satisfaction. I want to end up with a recordset with the component-asset type combinations that are missing. This would significantly improve the speed of my program (120 times as fast)

I tried to use Except but this resulted in no records where I did expect them:

Select Distinct C.Code, AT.Code 
FROM dbo.astComponents C 
JOIN dbo.astAssetTypes AT ON AT.Id = C.AssetTypeId 

WHERE (C.Code= '0738.D100' AND AT.Code = '0738.M00_03.03') Or (C.Code= '0738.D101' AND AT.Code = '0738.L00_04.04')

Except Select C.Code, AT.Code From astComponents C Join astAssetTypes AT ON AT.Id = C.AssetTypeId

EDIT
As already mentioned, the desired output should be the missing component-asset type combinations. Example:

Component      Asset Type
0738.D101      0990.D10_03.03
0150.C101      0738.L00_04.04

SQL-Fiddle
Task: check whether the component-asset type combinations below exist in the fiddle database. If not, add these combinations to the output.

Component      Asset Type
0738.D100      0990.D10_03.03
0738.D101      0990.D10_03.03
0150.C101      0738.L00_04.04
0738.L004      0738.M00_03.03
0990.D103      0738.M00_03.03

1条回答
干净又极端
2楼-- · 2019-08-18 22:59

Not the final answer, as the method below is SLOW

In this method I use a loop that populates a variable which helps populating a temp table with all component-asset type combinations which should be checked. I then compare the values in the database with the temp table using a CTE.

Creating the temp table and executing the second query lasts for 5 seconds (with 1250 records in #Temp), which I deem to be too slow

arr = Range("B3:J" & LRow)
For i = 1 To LRow - 2
    ComponentCodeTemp = ComponentCodeTemp & "Insert Into #Temp (Component, AssetType) Values ('" & arr(i, 1) & "','" & arr(i, 9) & "');"
Next i

'Query
Set rs = getdata("Create Table #Temp(Component nvarchar(50) Collate Latin1_General_BIN, AssetType nvarchar(50) Collate Latin1_General_BIN) " & ComponentCodeTemp & _
    "; With Compare As (Select T.* From #Temp T), DBD As (Select Distinct Compare.Component,  Compare.AssetType From astComponents C Join astAssetTypes AT ON AT.Id = C.AssetTypeId Right Join #Temp Compare ON Compare.AssetType = AT.Code And Compare.Component = C.Code Where C.Code is null) " & _
    "Select * From DBD")

A better markup for the SQL query:

WITH 
    Compare AS (
                Select T.* FROM #Temp T
               ),
    DBD AS (
            Select Distinct Compare.Component,  Compare.AssetType From astComponents C
            Join astAssetTypes AT ON AT.Id = C.AssetTypeId
            Right Join #Temp Compare ON Compare.AssetType = AT.Code And Compare.Component = C.Code
            Where C.Code is null
            )
Select * From DBD
查看更多
登录 后发表回答