SQL - 只保留某些字段不匹配的列
SQL - Keep only columns that have some field that don't match
我每天更新 table,但我只想更新前一天修改过任何值的行。
例如,我有 2 tables(今天和昨天):
今天:
ID
姓名
月份
国家/地区
年
1
斯塔
4 月
牙买加
1992
2
丹尼
11 月
法国
1982
3
艾丽
六月
澳大利亚
2020
4
约翰
4 月
乌拉圭
1765
5
保罗
五月
加拿大
1990
昨天:
ID
姓名
月份
国家/地区
年
1
斯塔
4 月
牙买加
1992
2
丹尼
11 月
西班牙
1982
3
艾丽
七月
澳大利亚
2022
5
保罗
五月
加拿大
1990
所以我想创建一个 table 从今天开始只有 ID 2、3 和 4,因为 1 个或多个字段已更改,或者该行出现在 table 今天但它没有' t 出现在 table 昨天:
ID
姓名
月份
国家/地区
年
2
丹尼
11 月
法国
1982
3
艾丽
六月
澳大利亚
2020
4
约翰
4 月
乌拉圭
1765
我尝试使用 MINUS 函数,但我使用的是 MS-Access,但它不起作用。有 +100 列,所以我不能做类似的事情:
其中 Today.ID = Yesterday.ID AND (Today.NAME <> Yesterday.NAME 或 Today.COUNTRY <> Yesterday.COUNTRY 或 Today.YEAR <> Yesterday.YEAR)
您可以使用 not exists
:
select t.*
from today as t
where not exists (select 1
from yesterday as y
where y.id = t.id and y.name = t.name and
y.month = t.month and y.country = t.country and
y.year = t.year
);
虽然使用 SQL 是一场噩梦,但使用 VBA 和一些循环就变得相对容易了。类似的东西似乎有效:
Sub sCheckDifference()
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsToday As DAO.Recordset
Dim rsYesterday As DAO.Recordset
Dim strSQL As String
Dim strNoMatch As String
Dim lngCount As Long
Dim lngLoop1 As Long
Set db = DBEngine(0)(0)
db.Execute "DELETE * FROM tblNoMatch;"
Set rsToday = db.OpenRecordset("SELECT * FROM tblToday;")
If Not (rsToday.BOF And rsToday.EOF) Then
lngCount = rsToday.Fields.Count - 1
Do
strSQL = "SELECT * FROM tblYesterday WHERE ID=" & rsToday!id
Set rsYesterday = db.OpenRecordset(strSQL)
If Not (rsYesterday.BOF And rsYesterday.EOF) Then
For lngLoop1 = 1 To lngCount
If rsToday(lngLoop1) <> rsYesterday(lngLoop1) Then
strNoMatch = strNoMatch & rsToday!id & ","
Exit For
End If
Next lngLoop1
Else ' value doesn't exist in previous table
strNoMatch = strNoMatch & rsToday!id & ","
End If
rsToday.MoveNext
Loop Until rsToday.EOF
If Len(strNoMatch) > 0 Then ' have found some differences
If Right(strNoMatch, 1) = "," Then strNoMatch = Left(strNoMatch, Len(strNoMatch) - 1)
strSQL = "INSERT INTO tblNoMatch SELECT * FROM tblToday WHERE ID IN(" & strNoMatch & ");"
db.Execute strSQL
End If
End If
sExit:
rsToday.Close
rsYesterday.Close
Set rsToday = Nothing
Set rsYesterday = Nothing
Set db = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sCheckDifference", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
请注意,Name
、Month
和 Year
都是 Access 中的保留字,因此如果这些是真实的字段名称,则应进行更改。
我每天更新 table,但我只想更新前一天修改过任何值的行。
例如,我有 2 tables(今天和昨天):
今天:
ID | 姓名 | 月份 | 国家/地区 | 年 |
---|---|---|---|---|
1 | 斯塔 | 4 月 | 牙买加 | 1992 |
2 | 丹尼 | 11 月 | 法国 | 1982 |
3 | 艾丽 | 六月 | 澳大利亚 | 2020 |
4 | 约翰 | 4 月 | 乌拉圭 | 1765 |
5 | 保罗 | 五月 | 加拿大 | 1990 |
昨天:
ID | 姓名 | 月份 | 国家/地区 | 年 |
---|---|---|---|---|
1 | 斯塔 | 4 月 | 牙买加 | 1992 |
2 | 丹尼 | 11 月 | 西班牙 | 1982 |
3 | 艾丽 | 七月 | 澳大利亚 | 2022 |
5 | 保罗 | 五月 | 加拿大 | 1990 |
所以我想创建一个 table 从今天开始只有 ID 2、3 和 4,因为 1 个或多个字段已更改,或者该行出现在 table 今天但它没有' t 出现在 table 昨天:
ID | 姓名 | 月份 | 国家/地区 | 年 |
---|---|---|---|---|
2 | 丹尼 | 11 月 | 法国 | 1982 |
3 | 艾丽 | 六月 | 澳大利亚 | 2020 |
4 | 约翰 | 4 月 | 乌拉圭 | 1765 |
我尝试使用 MINUS 函数,但我使用的是 MS-Access,但它不起作用。有 +100 列,所以我不能做类似的事情: 其中 Today.ID = Yesterday.ID AND (Today.NAME <> Yesterday.NAME 或 Today.COUNTRY <> Yesterday.COUNTRY 或 Today.YEAR <> Yesterday.YEAR)
您可以使用 not exists
:
select t.*
from today as t
where not exists (select 1
from yesterday as y
where y.id = t.id and y.name = t.name and
y.month = t.month and y.country = t.country and
y.year = t.year
);
虽然使用 SQL 是一场噩梦,但使用 VBA 和一些循环就变得相对容易了。类似的东西似乎有效:
Sub sCheckDifference()
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsToday As DAO.Recordset
Dim rsYesterday As DAO.Recordset
Dim strSQL As String
Dim strNoMatch As String
Dim lngCount As Long
Dim lngLoop1 As Long
Set db = DBEngine(0)(0)
db.Execute "DELETE * FROM tblNoMatch;"
Set rsToday = db.OpenRecordset("SELECT * FROM tblToday;")
If Not (rsToday.BOF And rsToday.EOF) Then
lngCount = rsToday.Fields.Count - 1
Do
strSQL = "SELECT * FROM tblYesterday WHERE ID=" & rsToday!id
Set rsYesterday = db.OpenRecordset(strSQL)
If Not (rsYesterday.BOF And rsYesterday.EOF) Then
For lngLoop1 = 1 To lngCount
If rsToday(lngLoop1) <> rsYesterday(lngLoop1) Then
strNoMatch = strNoMatch & rsToday!id & ","
Exit For
End If
Next lngLoop1
Else ' value doesn't exist in previous table
strNoMatch = strNoMatch & rsToday!id & ","
End If
rsToday.MoveNext
Loop Until rsToday.EOF
If Len(strNoMatch) > 0 Then ' have found some differences
If Right(strNoMatch, 1) = "," Then strNoMatch = Left(strNoMatch, Len(strNoMatch) - 1)
strSQL = "INSERT INTO tblNoMatch SELECT * FROM tblToday WHERE ID IN(" & strNoMatch & ");"
db.Execute strSQL
End If
End If
sExit:
rsToday.Close
rsYesterday.Close
Set rsToday = Nothing
Set rsYesterday = Nothing
Set db = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sCheckDifference", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
请注意,Name
、Month
和 Year
都是 Access 中的保留字,因此如果这些是真实的字段名称,则应进行更改。