2

Microsoft Access 2010データベースを使用して、1つのテーブルから値をインポートし、それらをサマリーテーブルに追加しています。

私が抱えている問題の1つは、selectステートメントから前の値と次の値を見つけることです。

これは次のようになります。

JOINT          JOINT AHEAD             JOINT BEHIND
100103           200203
200203           300303                  100103
300303                                   200203

SQLコードを使用してこれを作成したい

4

2 に答える 2

1

相関サブクエリを検討するときは注意してください。それらは非常に遅くなる可能性があります。また、 2つの相関するサブクエリを含むクエリを作成すると、問題が拡大します。

ソーステーブルに含まれる行数が少ない場合(たとえば数十行)、速度の低下は問題にならない可能性があります。ただし、テーブルに1000行が含まれている場合は、間違いなくそれに気付くでしょう。また、JOINTフィールドにインデックスが付けられていない場合、パフォーマンスが非常に遅くなる可能性があります。

Accessセッション内からクエリを実行する場合は、相関サブクエリの代わりにドメイン関数(DMinおよび)を使用できます。DMaxドメイン機能はしばしば遅いと批判されます。ただし、この状況では、相関するサブクエリよりも劇的に高速になる可能性があります。

訂正DMin():およびDMax()関数を使用できるようにするために、Accessセッション内からクエリを実行する必要はありません。に基づいてADOレコードセットを開くVBScriptの例を添付しましたqryDomainFunctions。エラーなしで動作し、正しく報告しますRecordCount: 1000

joints主キーとして長整数フィールドを使用してテーブルを作成し、joint1000行を追加しました。次に、次の2つのクエリを作成しました。

qryCorrelatedSubqueries

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

qryDomainFunctions

SELECT
    j.joint,
    DMin("joint","joints","joint > " & [joint]) AS joint_ahead,
    DMax("joint","joints","joint < " & [joint]) AS joint_behind
FROM joints AS j;

QueryDurationこれは、以下の関数を使用して、これら2つのクエリの速度を比較したイミディエイトウィンドウからのトランスクリプトです。この関数は、期間をミリ秒単位で返します。

? QueryDuration("qryDomainFunctions")
 0 

? QueryDuration("qryCorrelatedSubqueries")
 889

jointsこれらのクエリは両方とも、フィールドのインデックスの恩恵を受けることに注意してください。インデックスを削除し、データベースを圧縮して、テストを再実行すると、次の結果が得られました。

? QueryDuration("qryDomainFunctions")
 16 

? QueryDuration("qryCorrelatedSubqueries")
 4570

これは私が使用したコードのモジュールです。QueryDurationパフォーマンス測定の最後の言葉ではありません。ただし、これら2つのクエリの相対速度の大まかなアイデアを提供するのに十分です。

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

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
于 2012-07-22T01:11:11.760 に答える
1

どうですか:

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;
于 2012-07-21T18:50:42.290 に答える