Left Join работает с таблицей, но не работает с запросом - PullRequest
1 голос
/ 28 марта 2012

Ожидается, что следующий левый запрос на присоединение в MS Access 2007

SELECT
Table1.Field_A,
Table1.Field_B,
qry_Table2_Combined.Field_A,
qry_Table2_Combined.Field_B,
qry_Table2_Combined.Combined_Field
FROM Table1
LEFT JOIN qry_Table2_Combined
 ON (Table1.Field_A = qry_Table2_Combined.Field_A) 
AND (Table1.Field_B = qry_Table2_Combined.Field_B);

вернет мне этот результат:

+--------+---------+---------+---------+----------------+
|Field_A | Field_B | Field_A | Field_B | Combined_Field |
+--------+---------+---------+---------+----------------+
|1       |         |         |         |                |
+--------+---------+---------+---------+----------------+
|1       |         |         |         |                |
+--------+---------+---------+---------+----------------+
|2       |1        |2        |1        |John, Doe       |
+--------+---------+---------+---------+----------------+
|2       |2        |         |         |                |
+--------+---------+---------+---------+----------------+

[Table1] имеет 4 записи, [qry_Table2_Combined] имеет1 запись.

Но это дает мне следующее:

+--------+---------+---------+---------+----------------+
|Field_A | Field_B | Field_A | Field_B | Combined_Field |
+--------+---------+---------+---------+----------------+
|2       |1        |2        |1        |John, Doe       |
+--------+---------+---------+---------+----------------+
|2       |2        |2        |         |,               |
+--------+---------+---------+---------+----------------+

Действительно странно, что [Combined_Field] имеет запятую во втором ряду.Я использую запятую для объединения двух полей в [qry_Table2_Combined].

Если левый запрос на соединение использует таблицу, созданную из запроса [qry_Table2_Combined], он работает как положено.

Почему это левое соединениезапрос не дает одинаковый результат для запроса и таблицы?И как я могу получить правильные результаты, используя запрос в левом соединении?

Ответы [ 3 ]

3 голосов
/ 29 марта 2012

Глядя на вашу логику, кажется, что вам нужны только комбинированные поля, где field_A = "2" (ВЫБЕРИТЕ '2' AS Field_A). Я подозреваю, что это вызывает проблему. Можно ли найти решение по-другому, например:

SELECT 
   t1.Field_A, 
   t1.Field_B, 
   t2.Field_B As t2B, 
   [t2].[Col_1] & ", " & [t2].[Col_2] AS Combined
FROM t1 LEFT JOIN t2 
ON t1.Field_B = t2.Field_B
WHERE t1.Field_A="2"
UNION ALL
SELECT  
   t1.Field_A, 
   t1.Field_B, 
   "None" As t2B, 
   "None" AS Combined
FROM t1 
WHERE t1.Field_A<>"2"
1 голос
/ 29 марта 2012

Объединение: измените операторы & на +, и результат должен быть таким, как ожидалось.


Пропущенные строки: я могу воспроизвести эту проблему, но не могу объяснить ее, кроме как сказатьа) это, вероятно, ошибка, и б) она, вероятно, никогда не будет исправлена: (

Для здравомыслия я протестировал тот же код в SQL Server, и он работает, как и ожидалось.

В целом внешнее соединение может быть смоделировано с использованием объединения и дополнения пропущенных значений например, псевдокод:

( A JOIN B )
UNION
( A NOT MATCH B { A.*, <pad values for B> } )

В вашем случае и в Access SQL:

SELECT Table1.Field_A, Table1.Field_B,  
       qry_Table2_Combined.Field_A,  
       qry_Table2_Combined.Field_B,  
       qry_Table2_Combined.Combined_Field  
  FROM Table1  
       INNER JOIN qry_Table2_Combined  
          ON (Table1.Field_A = qry_Table2_Combined.Field_A)  
             AND (Table1.Field_B = qry_Table2_Combined.Field_B)
UNION ALL
SELECT Table1.Field_A, Table1.Field_B,  
       NULL AS Field_A,  
       NULL AS Field_B,  
       NULL AS Combined_Field  
  FROM Table1  
 WHERE NOT EXISTS ( SELECT * 
                      FROM qry_Table2_Combined 
                     WHERE (Table1.Field_A = qry_Table2_Combined.Field_A)  
                            AND (Table1.Field_B = qry_Table2_Combined.Field_B) );

Вышепохоже, дает ожидаемые вами результаты.


Доступ к репро-коду с исправлением конкатенации, раскомментированный код для предлагаемого обходного пути:

Sub EXfewfTempler()

  On Error Resume Next
  Kill Environ$("temp") & "\DropMe.mdb"
  On Error GoTo 0

  Dim cat
  Set cat = CreateObject("ADOX.Catalog")

  With cat
    .Create _
        "Provider=Microsoft.Jet.OLEDB.4.0;" & _
        "Data Source=" & _
        Environ$("temp") & "\DropMe.mdb"

    With .ActiveConnection

      Dim Sql As String

      Sql = "CREATE TABLE Table1 (  Field_A VARCHAR(10),  Field_B VARCHAR(10) );"
      .Execute Sql

      Sql = "CREATE TABLE Table2 ( Field_B VARCHAR(10),  Col_1 VARCHAR(10),  Col_2 VARCHAR(10));"
      .Execute Sql

      Sql = "CREATE VIEW qry_Table2_Combined AS SELECT '2' AS Field_A, Table2.Field_B, Table2.Col_1 + ', ' + Table2.Col_2 AS Combined_Field FROM Table2; "
      .Execute Sql

      Sql = "INSERT INTO Table1 VALUES (1, NULL);"
      .Execute Sql
      Sql = "INSERT INTO Table1 VALUES (1, NULL);"
      .Execute Sql
      Sql = "INSERT INTO Table1 VALUES (2, 1);"
      .Execute Sql
      Sql = "INSERT INTO Table1 VALUES (2, 2);"
      .Execute Sql
      Sql = "INSERT INTO Table2 VALUES (1, 'John', 'Doe');"
      .Execute Sql

      Sql = _
          "SELECT " & _
          "Table1.Field_A, " & _
          "Table1.Field_B, " & _
          "qry_Table2_Combined.Field_A, " & _
          "qry_Table2_Combined.Field_B, " & _
          "qry_Table2_Combined.Combined_Field " & _
          "FROM Table1 " & _
          "LEFT JOIN qry_Table2_Combined " & _
          " ON (Table1.Field_A = qry_Table2_Combined.Field_A) " & _
          "AND (Table1.Field_B = qry_Table2_Combined.Field_B);"

'      Sql = _
'          "SELECT Table1.Field_A, Table1.Field_B, " & _
'          "       qry_Table2_Combined.Field_A, " & _
'          "       qry_Table2_Combined.Field_B, " & _
'          "       qry_Table2_Combined.Combined_Field " & _
'          "  FROM Table1 " & _
'          "       INNER JOIN qry_Table2_Combined " & _
'          "          ON (Table1.Field_A = qry_Table2_Combined.Field_A) " & _
'          "             AND (Table1.Field_B = qry_Table2_Combined.Field_B) " & _
'          "UNION ALL " & _
'          "SELECT Table1.Field_A, Table1.Field_B, " & _
'          "       NULL AS Field_A, " & _
'          "       NULL AS Field_B, " & _
'          "       NULL AS Combined_Field " & _
'          "  FROM Table1 " & _
'          " WHERE NOT EXISTS ( SELECT * " & _
'          "                      FROM qry_Table2_Combined " & _
'          "                     WHERE (Table1.Field_A = qry_Table2_Combined.Field_A) " & _
'          "                            AND (Table1.Field_B = qry_Table2_Combined.Field_B) );"


      Dim rs
      Set rs = .Execute(Sql)
      MsgBox rs.GetString(2, , vbTab & vbTab, , "<NULL>")

    End With
    Set .ActiveConnection = Nothing
  End With
End Sub
0 голосов
/ 29 марта 2012

не является ли это проблемой при разборе MSAccess. для теста измените имена полей в запросе на Field_C и Field_D и посмотрите, не возникает ли у вас такая же проблема

...