Access 2010 Странное поведение - PullRequest
2 голосов
/ 02 февраля 2012

Доброе утро всем, я делаю запрос в Access 2010, и у меня странное поведение, поэтому я хотел бы услышать ваше мнение, вот и мы:

SELECT X.*, L.CodLinea
FROM (
   SELECT TOP 1 'LBASE' AS CodLinea, 'Linea Base' AS Descrizione FROM ParametriAzienda
)  AS X LEFT JOIN Linee AS L 
ON X.CodLinea = L.CodLinea

Внутренний запросдает всегда ОДНУ строку с двумя столбцами, которые должны быть примерно такими:

CodLinea  |  Descrizione
----------+--------------
  LBASE   |  Linea Base

Теперь при выполнении левого соединения, как описано выше, должна возвращаться ОДНА строка с другим столбцом с именем L.CodLinea со значением, равным LBASE'или NULL в зависимости от того, есть ли в таблице Linee значение LBASE.Таким образом, результатом может быть:

  X.CodLinea  |  X.Descrizione  |  L.CodLinea
+-------------+-----------------+--------------+
    LBASE     |  Linea Base     |   LBASE      

, если значение существует, или

  X.CodLinea  |  X.Descrizione  |  L.CodLinea
+-------------+-----------------+--------------+
    LBASE     |  Linea Base     |   null      

, если значение не существует.На самом деле я получаю:

  X.CodLinea  |  X.Descrizione  |  L.CodLinea
+-------------+-----------------+--------------+
    LBASE     |  Linea Base     |   0          
    LBASE     |  Linea Base     |   0          
    LBASE     |  Linea Base     |   0          
    LBASE     |  Linea Base     |   0          
    LBASE     |  Linea Base     |   0          

Это определенно не может быть возможным, потому что: а) я должен получить только один ряд;б) 0 не равно или как LBASE.Если я использую WHERE вместо LEFT JOIN (аналогично INNER JOIN) или RIGHT JOIN, результаты будут правильными (0 строк).

В чем может быть проблема?

РЕДАКТИРОВАТЬ: На самом деле ParametriAzienda имеет только одну строку, и Linee не содержит значение LBASE.

1 Ответ

1 голос
/ 02 февраля 2012

Проблема TOP 1: либо вы неправильно поняли его использование (ошибка в вашем коде), либо это ошибка в движке.

Лично я всегда использую DISTINCT, потому что это стандартный SQLи я понимаю его использование :) Действительно, когда я проверял это, замена TOP 1 на DISTINCT превращает ваш фактический результат в ожидаемый.

Вот мое воспроизведение.Приведенный ниже VBA создает новый файл данных во временной папке с таблицами и образцами данных.Ссылки не требуются, просто скопируйте + вставьте в любой модуль VBA, например, используйте Excel:

Sub NotTop1()

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

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

  With cat
  .Create _
        "Provider=Microsoft.ACE.OLEDB.12.0;" & _
        "Data Source=" & _
        Environ$("temp") & "\DropMe.accdb"

    With .ActiveConnection

      Dim Sql As String

      Sql = _
      "CREATE TABLE ParametriAzienda (x INTEGER NOT NULL);"
      .Execute Sql

      Sql = _
      "INSERT INTO ParametriAzienda (x) VALUES (1);"
      .Execute Sql

      Sql = _
      "CREATE TABLE Linee (CodLinea CHAR(1) NOT NULL);"
      .Execute Sql

      Dim i As Long
      For i = 0 To 4
        Sql = _
        "INSERT INTO Linee (CodLinea) VALUES ('0');"
        .Execute Sql
      Next

      Sql = _
      "SELECT X.*, L.CodLinea " & _
      "FROM ( " & _
      "   SELECT TOP 1 'LBASE' AS CodLinea, 'Linea Base' AS Descrizione FROM ParametriAzienda " & _
      ")  AS X LEFT JOIN Linee AS L  " & _
      "ON X.CodLinea = L.CodLinea"

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

  Sql = Replace$(Sql, "TOP 1", "DISTINCT")

  Set rs = .Execute(Sql)
  MsgBox rs.GetString(2, , vbTab & vbTab, , "<null>")        
    End With
    Set .ActiveConnection = Nothing
  End With
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...