使用SQL在access中查找上一个和下一个值

使用SQL在access中查找上一个和下一个值,sql,ms-access,Sql,Ms Access,我正在使用Microsoft Access 2010数据库从一个表中导入值,并将其附加到摘要表中 我遇到的问题之一是从select语句中查找上一个和下一个值 这将如下所示 JOINT JOINT AHEAD JOINT BEHIND 100103 200203 200203 300303 100103 300303

我正在使用Microsoft Access 2010数据库从一个表中导入值,并将其附加到摘要表中

我遇到的问题之一是从select语句中查找上一个和下一个值

这将如下所示

JOINT          JOINT AHEAD             JOINT BEHIND
100103           200203
200203           300303                  100103
300303                                   200203
我想使用SQL代码创建它,那么:

SELECT a.JOINT, 
      (SELECT TOP 1 Joint 
       FROM Joint b 
       WHERE b.JOINT>a.JOINT 
       ORDER BY Joint) AS Ahead,
      (SELECT TOP 1 Joint 
       FROM Joint b 
       WHERE b.JOINT<a.JOINT 
       ORDER BY Joint DESC) AS Behind
FROM Joint AS a;

考虑相关子查询时要谨慎。它们可能非常慢。如果您构建了一个包含两个相关子查询的查询,您将放大问题

如果源表包含的行数很少,比如几十行,那么速度可能不是问题。但是,如果表格包含一千行,您肯定会注意到它。如果您的关节字段没有索引,性能可能会非常慢

如果要在访问会话中运行查询,可以使用域函数DMin和DMax,而不是相关子查询。域函数经常被批评为速度慢。然而,在这种情况下,它们可能比相关子查询快得多

更正:您不需要在Access会话中运行查询,就可以使用DMin和DMax函数。我附加了一个VBScript示例,它根据我的qryDomainFunction打开一个ADO记录集。它工作正常,并正确报告RecordCount:1000

我创建了一个名为joints的表,其中一个长整型字段joint作为主键,并添加了1000行。然后我创建了以下两个查询:

qryCorrelated子查询:

请注意,这两个查询都受益于joints字段上的索引。当我删除索引、压缩数据库并重新运行测试时,我得到了以下结果:

? QueryDuration("qryDomainFunctions")
 16 

? QueryDuration("qryCorrelatedSubqueries")
 4570
这是我使用的代码模块。查询时间决不是绩效衡量的最后一个词。不过,这足以让我们大致了解这两个查询的相对速度

Option Compare Database
Option Explicit

Private Declare Function apiGetTickCount Lib "kernel32" _
 Alias "GetTickCount" () As Long

Public Function QueryDuration(ByVal pQueryName As String) As Long
    Dim db As DAO.Database
    Dim lngStart As Long
    Dim lngDone As Long
    Dim rs As DAO.Recordset

    Set db = CurrentDb()
    lngStart = apiGetTickCount() ' milliseconds '
    Set rs = db.OpenRecordset(pQueryName, dbOpenSnapshot)
    If Not rs.EOF Then
        rs.MoveLast
    End If
    lngDone = apiGetTickCount()
    rs.Close
    Set rs = Nothing
    Set db = Nothing
    QueryDuration = lngDone - lngStart
End Function
DomainFunctionsQuery.vbs:


我不知道该怎么做,很抱歉我是个笨蛋。我只有一个关节字段,前面有两个确定字段,behindI已经调用了你的表关节,因为我不知道它叫什么。有两个子查询引用该表,但给它一个不同的别名。在外部查询中将关节作为a,在子查询中将关节作为b。As是可选的,所以我省略了它。
? QueryDuration("qryDomainFunctions")
 0 

? QueryDuration("qryCorrelatedSubqueries")
 889
? QueryDuration("qryDomainFunctions")
 16 

? QueryDuration("qryCorrelatedSubqueries")
 4570
Option Compare Database
Option Explicit

Private Declare Function apiGetTickCount Lib "kernel32" _
 Alias "GetTickCount" () As Long

Public Function QueryDuration(ByVal pQueryName As String) As Long
    Dim db As DAO.Database
    Dim lngStart As Long
    Dim lngDone As Long
    Dim rs As DAO.Recordset

    Set db = CurrentDb()
    lngStart = apiGetTickCount() ' milliseconds '
    Set rs = db.OpenRecordset(pQueryName, dbOpenSnapshot)
    If Not rs.EOF Then
        rs.MoveLast
    End If
    lngDone = apiGetTickCount()
    rs.Close
    Set rs = Nothing
    Set db = Nothing
    QueryDuration = lngDone - lngStart
End Function
Option Explicit
Dim cn, rs
Set cn = CreateObject("ADODB.Connection")
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source='database1.mdb'"
Set rs = CreateObject("ADODB.Recordset")
rs.CursorLocation = 3 ' adUseClient '
rs.Open "qryDomainFunctions", cn, 3 ' adOpenStatic = 3 '
WScript.Echo "RecordCount: " & rs.RecordCount
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing