Sql 访问2010奇怪的行为
大家早上好,我在Access 2010中进行一个查询,我发现一个奇怪的行为,所以我想听听你们的意见,现在开始:Sql 访问2010奇怪的行为,sql,ms-access,Sql,Ms Access,大家早上好,我在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 内部查询始终提供一行,其中包含两个列,
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
这绝对不可能,因为:a)我应该只得到一排;b) 0不等于或类似于LBASE。如果使用WHERE而不是LEFT连接(类似于内部连接)或RIGHT连接,则结果是正确的(0行)
怎么回事
编辑:实际上ParametriAzienda只有一行,而Linee不包含LBASE值。问题在于
TOP 1
:要么您误解了它的用法(代码中的错误),要么它是引擎中的错误
就我个人而言,我总是使用DISTINCT
,因为它是标准SQL(我理解它的用法:)事实上,当我测试这个时,用DISTINCT
替换TOP 1
,将实际结果转化为预期结果
这是我的报告。下面的VBA在temp文件夹中创建一个新的数据文件,其中包含表格和示例数据。无需参考,只需复制并粘贴到任何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
Sub NotTop1()
出错时继续下一步
Kill environo$(“temp”)和“\DropMe.accdb”
错误转到0
昏猫
设置cat=CreateObject(“ADOX.Catalog”)
和猫
.创造_
“Provider=Microsoft.ACE.OLEDB.12.0;”_
“数据源=”&_
环境$(“临时”)和“\DropMe.accdb”
使用.ActiveConnection
将Sql设置为字符串
Sql=_
“创建表ParameteriAziEnda(x整数非空);”
.执行Sql
Sql=_
“将NDA(x)值(1)插入到参数中;”
.执行Sql
Sql=_
“创建表Linee(CodLinea CHAR(1)不为NULL);”
.执行Sql
我想我会坚持多久
对于i=0到4
Sql=_
“插入Linee(CodLinea)值('0');”
.执行Sql
下一个
Sql=_
“选择X.*,L.CodLinea”和_
从(&)_
“选择前1个‘LBASE’作为CodLinea,选择Linea Base作为Parameterriazienda中的描述”&_
“”)作为X左连接线作为L“&”_
“关于X.CodLinea=L.CodLinea”
暗淡的
设置rs=.Execute(Sql)
MsgBox rs.GetString(2,vbTab和vbTab,“”)
Sql=Replace$(Sql,“前1名”,“不同”)
设置rs=.Execute(Sql)
MsgBox rs.GetString(2,vbTab和vbTab,“”)
以
Set.ActiveConnection=Nothing
以
端接头
我也在Jet 4.0(.mdb)上进行了测试,得到了相同的结果,即Access 2010和ACE(.accdb)都没有问题。嗯,我想这不是问题所在。我们尝试过没有前1行,但它仍然有5行,DISTINCT也是。实际上,ParametriAzienda只有一行…@IssamTP:你试过运行我的代码吗?你会得到不同的结果吗?如果没有,您能否更改我的代码以更好地反映您的场景?e、 g.可能您的数据与您的数据完全不同,您只提供了它实际可能是什么的提示。我会让您知道,我还添加了一些关于db数据的信息。@IssamTP:注意,我的数据已经满足您刚才添加的条件(“ParameterAzienda只有一行,Linee不包含LBASE值”)。我已经测试了您的代码,伙计,你是个天才,这很管用。事实上,当我第一次要求我的同事用DISTINCT更改TOP 1时,他误解了我,并将DISTINCT放在了外部查询中。