问题
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:
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
来源:https://stackoverflow.com/questions/56775570/query-to-select-records-that-do-not-appear-in-db