IssamTP
IssamTP

Reputation: 2440

Access 2010 Strange behavior

Goodmorning everybody, I'm doing a query in Access 2010 and I'm getting a strange behavior, so I'd like to hear your opinion, here we go:

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

The inner query gives always ONE row with two colums that should be something like:

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

Now, doing a left join like above should return ONE row with another column called L.CodLinea with a value that is EQUAL to 'LBASE' or NULL depending if the table Linee has got 'LBASE' inside. So, the result can be:

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

if the value exists, or

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

if the value doesn't exist. Indeed what I get is:

  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          

That definitely can't be possible, becasue: a) I should get only one row; b) 0 is NOT equal or like to LBASE. If I use the WHERE instead of LEFT JOIN (similar to an INNER JOIN) the or a RIGHT JOIN, the results are correct (0 rows).

What can be the matter?

EDIT: Actually ParametriAzienda has got only one row and Linee does not contain LBASE value.

Upvotes: 2

Views: 172

Answers (1)

onedaywhen
onedaywhen

Reputation: 57023

The problem is TOP 1: either you have misunderstood its use (bug in your code) or it's a bug in the engine.

Personally, I always use DISTINCT because it is Standard SQL (and I understand its use :) Indeed, when I tested this, replacing TOP 1 with DISTINCT turns your actual result into the expected result.

Here's my repro. The below VBA creates a new data file in temp folder, with tables and sample data. No references required, simply copy+paste into any VBA module e.g. use 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

Upvotes: 1

Related Questions