Запрос, выполненный SQL, показывает одни и те же результаты несколько раз (несколько копий одной и той же записи в запросе)

#sql #ms-access #join #vba

#sql #ms-access #Присоединиться #vba

Вопрос:

У меня есть запрос, выполняемый с помощью инструкции 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 amp; " " amp; v(count) amp; " 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 " amp; strTables amp; " 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" amp; 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

Комментарии:

1. Как это tblQuestionnaires связано с tblPatientHistoryBaseline ? Правильное ОБЪЕДИНЕНИЕ, вероятно, исправит это.

2. У них только один и тот же идентификационный номер (связанный). Как бы вы присоединились к ним?

Ответ №1:

Вы не указываете, как tblQuestionnaires это связано с tblPatientHistoryBaseline ? Правильное 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*'
  

Комментарии:

1. В запросе может быть до 4 таблиц — все с соответствующими идентификационными номерами.

2. Как будет выглядеть синтаксис для всех 4 таблиц, находящихся в запросе?? (tblTreatments и tblFollowUp) Если вы не возражаете! Большое вам спасибо!!!

3. Что ID представляет поле? Является ID ли поле специфичным для пациента?

4. Смотрите мое редактирование. Вам нужно будет указать точные поля, которые вам нужны в запросе.

5. Потрясающе!! Спасибо вам большое, задержитесь !! 🙂

Ответ №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, но если вы добавите к ним соответствующий псевдоним, все будет хорошо.