由 SQL 完成的查询多次显示相同的结果(查询中同一记录的多个副本)

Posted

技术标签:

【中文标题】由 SQL 完成的查询多次显示相同的结果(查询中同一记录的多个副本)【英文标题】:Query done by SQL showing same results multiple times (multiple copies of same record in query) 【发布时间】:2014-06-18 15:45:08 【问题描述】:

我有一个通过 SQL 语句进行的查询。我得到了正确的结果,只是每个结果在查询中重复了 4 次。我很困惑为什么我会得到 4 个相同结果的副本。

这是我的表单代码:

Dim strTables As String
Private Sub btnFollowUpQs_Click()
    If (btnFollowUpQs.Value = True) Then
        Set db = CurrentDb()
        Set rs = db.OpenRecordset(btnFollowUpQs.Caption)
        Dim fld As DAO.Field
        For Each fld In rs.Fields
            Me.lstVariablesFollowUpQs.AddItem (fld.Name)
        Next
        Set fld = Nothing
        db.Close
        strTables = strTables + "," + btnFollowUpQs.Caption
    Else
        lstVariablesFollowUpQs.RowSource = ""
        strTables = Replace(strTables, "," + btnFollowUpQs.Caption, "")
    End If
    Debug.Print strTables
End Sub

Private Sub btnBaseline_Click()
    If (btnBaseline.Value = True) Then
        Set db = CurrentDb()
        Set rs = db.OpenRecordset(btnBaseline.Caption)
        Dim fld As DAO.Field
        For Each fld In rs.Fields
            Me.lstVariablesBaseline.AddItem (fld.Name)
        Next
        Set fld = Nothing
        db.Close
        strTables = strTables + "," + btnBaseline.Caption
    Else
        lstVariablesBaseline.RowSource = ""
        strTables = Replace(strTables, "," + btnBaseline.Caption, "")
    End If
        Debug.Print strTables
End Sub

Private Sub btnTreatments_Click()
    If (btnTreatments.Value = True) Then
        Set db = CurrentDb()
        Set rs = db.OpenRecordset(btnTreatments.Caption)
        Dim fld As DAO.Field
        For Each fld In rs.Fields
            Me.lstVariablesTreatments.AddItem (fld.Name)
        Next
        Set fld = Nothing
        db.Close
        strTables = strTables + "," + btnTreatments.Caption
    Else
        lstVariablesTreatments.RowSource = ""
        strTables = Replace(strTables, "," + btnTreatments.Caption, "")
    End If
        Debug.Print strTables
End Sub

Private Sub btnQuestionnaires_Click()
    If (btnQuestionnaires.Value = True) Then
        Set db = CurrentDb()
        Set rs = db.OpenRecordset(btnQuestionnaires.Caption)
        Dim fld As DAO.Field
        For Each fld In rs.Fields
            Me.lstVariablesQuestionnaires.AddItem (fld.Name)
        Next
        Set fld = Nothing
        db.Close
        strTables = strTables + "," + btnQuestionnaires.Caption
    Else
        lstVariablesQuestionnaires.RowSource = ""
        strTables = Replace(strTables, "," + btnQuestionnaires.Caption, "")
    End If
        Debug.Print strTables
End Sub

Private Function createSQL(ByRef lstCtrl As Control, v() As String) As String
        Dim count As Integer
        count = 0
        With lstCtrl
            For Each varSelected In .ItemsSelected
                If Not IsNull(varSelected) Then
                    Dim sel As String
                    sel = (lstCtrl.Column(0, varSelected))
                    strSQL = strSQL + sel & " " & v(count) & " AND "
                End If
                count = count + 1
            Next
        End With

        createSQL = strSQL
End Function

Private Sub btnBuildQuery_Click()

    If Left(strTables, 1) = "," Then
        strTables = Right(strTables, Len(strTables) - 1)
    End If

    Dim tables() As String
    tables = Split(strTables, ",")


    Dim strSQL As Variant
    strSQL = "SELECT * FROM " & strTables & " WHERE "

    For Each Table In tables

        Dim values() As String

        Select Case Table

        Case "tblPatientHistoryBaseline"
            values = Split(txtSearchValueBaseline, ",")
            strSQL = strSQL + createSQL(lstVariablesBaseline, values)
        Case "tblQuestionnaires"
            values = Split(txtSearchValueQuestionnaires, ",")
            strSQL = strSQL + createSQL(lstVariablesQuestionnaires, values)
        Case "tblTreatments"
            values = Split(txtSearchValueTreatments, ",")
           strSQL = strSQL + createSQL(lstVariablesTreatments, values)
        Case "tblFollowUpQs"
            values = Split(txtSearchValueFollowUpQs, ",")
           strSQL = strSQL + createSQL(lstVariablesFollowUpQs, values)
        End Select

    Next
        strSQL = Left(strSQL, Len(strSQL) - 5)

    Debug.Print (strSQL)
    Dim qdf As QueryDef
    Set qdf = CurrentDb.CreateQueryDef("qry" & txtQueryName, strSQL)
    DoCmd.OpenQuery qdf.Name
End Sub

这是查询返回的内容:

LastName    FirstName    ID          Visit
Line        Georgia      1234567     0
Line        Georgia      1234567     0
Line        Georgia      1234567     0
Line        Georgia      1234567     0
Doe         Jane         0123456     0
Doe         Jane         0123456     0
Doe         Jane         0123456     0
Doe         Jane         0123456     0

这是我生成的示例 SQL:

SELECT * FROM tblQuestionnaires, tblPatientHistoryBaseline WHERE Visit = 0 AND LastName Like '*e*'

我猜我的 SQL 出了点问题,但我不知道是什么问题。

谢谢!

'编辑----------------- 姓氏来自 tblPatientHistoryBaseline, 访问来自 tblQuestionnaires

【问题讨论】:

tblQuestionnairestblPatientHistoryBaseline 有什么关系?适当的 JOIN 可能会解决此问题。 他们只有相同的ID号(相关)。您将如何加入他们? 【参考方案1】:

您没有指定tblQuestionnairestblPatientHistoryBaseline 的关系?一个合适的JOIN 可能会解决这个问题:

SELECT * 
FROM tblQuestionnaires AS q
  INNER JOIN tblPatientHistoryBaseline AS ph ON q.ID = ph.ID
WHERE Visit = 0 
  AND LastName Like '*e*'

我不太确定您选择的字段来自哪个表。如果任一表中有多个记录,上述查询仍可能产生重复。如果是这种情况,您可以将 DISTINCT 语句添加到查询中并指定您需要的字段:

SELECT DISTINCT LastName, FirstName, ph.ID, Visit
FROM tblQuestionnaires AS q
  INNER JOIN tblPatientHistoryBaseline AS ph ON q.ID = ph.ID
WHERE Visit = 0 
  AND LastName Like '*e*'

编辑:

SELECT DISTINCT ph.ID, q.fieldname, ph.fieldname, t.fieldname, f.fieldname 
FROM tblQuestionnaires AS q
  INNER JOIN tblPatientHistoryBaseline AS ph ON q.ID = ph.ID
  INNER JOIN tblTreatments AS t ON t.ID = ph.ID
  INNER JOIN tblFollowUp AS f ON f.ID = ph.ID
WHERE Visit = 0 
  AND LastName Like '*e*'

【讨论】:

查询中最多可以有 4 个表 - 都具有匹配的 ID 号。 查询中的所有 4 个表的语法是什么样的? (tblTreatments 和 tblFollowUp)如果您不介意!非常感谢!!! ID 字段代表什么? ID 字段是否特定于患者? 查看我的编辑。您必须在查询中指定所需的确切字段。 太棒了!非常非常感谢灵儿!! :)【参考方案2】:

在这种情况下,必须加入它们。例如,您的代码应编写为仅指定调查表中的匹配行。也就是说,

SELECT * 
FROM tblQuestionnaires, tblPatientHistoryBaseline 
WHERE Visit = 0 
AND LastName Like '*e*'
AND tblQuestionnaires.id = tblPatientHistoryBaseline.id

但我也建议使用较新的(无论如何是过去十年)语法:

SELECT * 
FROM tblQuestionnaires q
  INNER JOIN tblPatientHistoryBaseline b
    ON q.id = b.id
WHERE q.Visit = 0 
AND b.LastName Like '*e*'

我不确定您的 VISIT 列或 LASTNAME 列来自哪里,但如果您在它们前面加上正确的别名,一切都会好起来的。

【讨论】:

以上是关于由 SQL 完成的查询多次显示相同的结果(查询中同一记录的多个副本)的主要内容,如果未能解决你的问题,请参考以下文章

优化SQL,CASE中同一行多次

SQL查找某一字段相同,某一字段不同的数据

sql多表连接查询问题

SQL 多次返回相同的结果

T-SQL,在视图中重复相同的标量子查询性能

meteor apollo graphql/sequelize 缓存查询结果,避免多次相同查询