比较在MS Access中共享公共标识符的所有列

时间:2014-08-20 17:28:30

标签: sql ms-access ms-access-2007

美好的一天。 我正在进行记录查询的比较,并且无法找到更简单的方法。这是倒计时:

基本上,与我合作的两个人一直在输入数据,因此我们研究中的每个参与者都会在我们的数据库中有两个记录。我必须对这些记录进行比较并返回所有差异,以便在进一步审查时对其进行检查和修复。想不出一个简单的方法 - 有大量的字段,我宁愿避免手动比较每一列。

是否有比较以下方法: testdata

我想比较参与者ID相同的所有列。最终目标是为每个参与者制作一列所有差异。

有什么想法吗?我的第一次尝试涉及拉出Count(参与者ID)> 1的所有记录,然后在我们正在检查的所有表上加入此记录。因此,每个参与者有2行 - 每次输入一次,输入数据库。然后我将这些记录并排放入一行,因此有aType_1,bType_1,aType_2,bType_2等。然后我开始为每个单独的列对编写比较,例如。 aType_1<> bType_1,并返回ID。如果我想浓缩成一个差异列表,这实际上需要大量的编码和大量的联合查询。我想不出一个简单的方法来做到这一点......提前感谢您的任何想法! :)

3 个答案:

答案 0 :(得分:0)

希望我明白你的意思。

SELECT a.Type_1, b.Type_1, a.Type_2, b.Type_2FROM table a
INNER JOIN table b ON b.ParticipantID = a.ParticipantID
WHERE a.Type_1<>b.Type_1 AND a.Type_2<>b.Type_2等。

答案 1 :(得分:0)

这是我设法得到的。我猜你的管理距离不远。但这里有所作为。 (哦,这是在MySql&gt; _&lt;)

假设您的参与者数据表具有某种唯一值列(主键?),您可以执行以下操作:

如果这是你的表结构:

mysql> describe foo;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| pid   | int(11) | YES  |     | NULL    |       |
| type1 | int(11) | YES  |     | NULL    |       |
| type2 | int(11) | YES  |     | NULL    |       |
| type3 | int(11) | YES  |     | NULL    |       |
| pk    | int(11) | YES  | UNI | NULL    |       |
+-------+---------+------+-----+---------+-------+
5 rows in set (0.00 sec)

您的数据如下:

mysql> select * from foo;
+------+-------+-------+-------+------+
| pid  | type1 | type2 | type3 | pk   |
+------+-------+-------+-------+------+
|    1 |    14 |    24 |    34 |    1 |
|    1 |    15 |    24 |    34 |    2 |
|    2 |    15 |    24 |    34 |    3 |
|    2 |    15 |    25 |    34 |    4 |
|    3 |    15 |    25 |    34 |    5 |
+------+-------+-------+-------+------+
5 rows in set (0.00 sec)

以下查询返回具有匹配pid的行的比较:

mysql> select  a.pid, a.type1 <> b.type1 as t1, a.type2 <> b.type2 as t2, a.type3 <> b.type3 as t3 from foo a join foo b on a.pid = b.pid where a.pk != b.pk group by a.pid having count(a.pid) > 1;
+------+------+------+------+
| pid  | t1   | t2   | t3   |
+------+------+------+------+
|    1 |    1 |    0 |    0 |
|    2 |    0 |    1 |    0 |
+------+------+------+------+
2 rows in set (0.00 sec)

相同的查询,包括用于参考的原始列值:

mysql> select *, a.pid, a.type1 <> b.type1 as t1, a.type2 <> b.type2 as t2, a.type3 <> b.type3 as t3 from foo a join foo b on a.pid = b.pid where a.pk != b.pk group by a.pid having count(a.pid) > 1;
+------+-------+-------+-------+------+------+-------+-------+-------+------+------+------+------+------+
| pid  | type1 | type2 | type3 | pk   | pid  | type1 | type2 | type3 | pk   | pid  | t1   | t2   | t3   |
+------+-------+-------+-------+------+------+-------+-------+-------+------+------+------+------+------+
|    1 |    15 |    24 |    34 |    2 |    1 |    14 |    24 |    34 |    1 |    1 |    1 |    0 |    0 |
|    2 |    15 |    25 |    34 |    4 |    2 |    15 |    24 |    34 |    3 |    2 |    0 |    1 |    0 |
+------+-------+-------+-------+------+------+-------+-------+-------+------+------+------+------+------+
2 rows in set (0.00 sec)

如果您想以某种方式避免写下每列的名称(因为您有100个),您可能需要考虑使用INFORMATION_SCHEMA表来通过存储过程获取列名。这也是MySql,但我确定MS-Access有一个等效的表。

希望这至少有一点帮助。 :P

答案 2 :(得分:0)

你熟悉VBA吗?当我必须实现类似于你的解决方案时,我遍历一个条目记录集的字段集合,并将其与第二个条目记录集的相同序号位置中的字段值进行比较。

    dim db as database
    dim rs1 as recordset
    dim rs2 as recordset
    dim i as integer
    dim bSame as boolean

    bsame = true  ' init
    set rs1 = db.openrecordset("qryEntry1")
    set rs2 = db.openrecordset("qryEntry2")
    for i = 0 to rs1.fields.count
       bSame = bSame and ( rs1(i) = rs2(i) )
    next

这是我使用的实际代码:

Public Function verify(sPatientID As String) As Boolean
' returns true if all fields for entries 1 and 2 match'
    Dim db As Database
    Dim qdef As QueryDef
    Dim rsDemo1 As Recordset
    Dim rsDemo2 As Recordset
    Dim rsDemoDiffs As Recordset
    Dim rs As Recordset
    Dim iDifferCountTestValues As Integer
    Dim iDifferCountDemo As Integer
    Dim iField As Integer
    Dim bDiffers As Boolean
    Dim bDemoEntered As Boolean
    Dim bValuesEntered As Boolean
    Dim bActive As Boolean
    Dim bWithdrawn As Boolean
    Dim bGroupSet As Boolean

    Set db = CurrentDb

    Set rs = db.OpenRecordset("select * from tblPatient where patientID = '" & sPatientID & "'")
    bActive = rs("isActive")
    bWithdrawn = rs("isWithdrawn")
    bGroupSet = (rs("groupID") > 0)

    Set qdef = db.QueryDefs("qryClearEntriesDifferPerPatient")
    qdef.Parameters("patientIDCrit") = sPatientID
    qdef.Execute

    Set qdef = db.QueryDefs("qrySetEntry1DiffersForPatient")
    qdef.Parameters("patientIDCrit") = sPatientID
    qdef.Execute

    Set qdef = db.QueryDefs("qrySetEntry2DiffersForPatient")
    qdef.Parameters("patientIDCrit") = sPatientID
    qdef.Execute

    Set qdef = db.QueryDefs("qryTestValueEntriesDifferForPatient")
    qdef.Parameters("patientIDCrit") = sPatientID
    Set rs = qdef.OpenRecordset
    bValuesEntered = Not rs.EOF
    If rs.EOF Then
        iDifferCountTestValues = 0
    Else
        iDifferCountTestValues = Abs(rs(1))     ' sum of true values is negative'
    End If

    db.Execute "Delete from tblDemographicEntriesDiffer where patientID = '" & sPatientID & "'"
    Set rsDemo1 = db.OpenRecordset("select * from tblPatientDemographics where patientID = '" & sPatientID & "' and entryID = 1")
    Set rsDemo2 = db.OpenRecordset("select * from tblPatientDemographics where patientID = '" & sPatientID & "' and entryID = 2")
    bDemoEntered = (Not rsDemo1.EOF) And (Not rsDemo2.EOF)
    Set rsDemoDiffs = db.OpenRecordset("Select * from tblDemographicEntriesDiffer")
    For iField = 2 To rsDemo1.Fields.Count - 1      ' skip comparison of entryID'
        If rsDemo1.Fields(iField).Value <> rsDemo2.Fields(iField).Value Then
            bDiffers = True
        ElseIf IsNull(rsDemo1.Fields(iField)) And Not IsNull(rsDemo2.Fields(iField)) Then
            bDiffers = True
        ElseIf Not IsNull(rsDemo1.Fields(iField)) And IsNull(rsDemo2.Fields(iField)) Then
            bDiffers = True
        Else
            bDiffers = False
        End If
        If bDiffers Then
            rsDemoDiffs.AddNew
            rsDemoDiffs("patientID") = sPatientID
            rsDemoDiffs("fieldName") = rsDemo1.Fields(iField).Name
            rsDemoDiffs("entry1") = rsDemo1.Fields(iField).Value
            rsDemoDiffs("entry2") = rsDemo2.Fields(iField).Value
            rsDemoDiffs.Update
        End If
    Next

    Set qdef = db.QueryDefs("qryDemoDiffersCountForPatient")
    qdef.Parameters("patientIDCrit") = sPatientID
    Set rs = qdef.OpenRecordset
    If rs.BOF And rs.EOF Then
        iDifferCountDemo = 0
    Else
        iDifferCountDemo = rs(1)
    End If

    verify = (iDifferCountTestValues + iDifferCountDemo = 0) And bDemoEntered And bActive
    If bWithdrawn Then
        verify = verify And bGroupSet
    Else
        verify = verify And bValuesEntered
    End If
    db.Execute "Update tblPatient set isVerified = " & verify & " where patientID = '" & sPatientID & "'"

    rsDemo1.Close
    rsDemo2.Close
    rsDemoDiffs.Close
    db.Close
End Function