このクエリが Access 2007 では実行されるが、Access 2010 では実行されないという事実について: 公開されている 2 つの違いのほとんどは特定のデータ型を扱っており、許容される SQL の仕様を扱っていないため、なぜそうなのかはわかりません。構文。
他のコメントが示唆しているように、犯人は条件文にあると思いAND NOT EXISTS (SELECT * FROM ...)
ます。
そうは言っても、同等のクエリ (理論上) と、そのパフォーマンスを向上させるためのヒントを提案します。
簡単な例
まず、このクエリが単語を使用して達成しようとしていることに取り組みましょう。Os_udaje
特定の関連フィールドを持つテーブルとのクロス結合 (デカルト積) を求めてKalendar
おり、3 つの異なるテーブルで 2 つの条件を満たす関連レコードを含む行を削除しています。後者の要件はNOT EXISTS
句によって達成されます。これは、書き直したいものです。
たとえば、次のとおりです。
SELECT TableA.Field1, TableB.Field2
FROM TableA, TableB WHERE
NOT EXISTS (SELECT *
FROM TableC
WHERE TableA.Field1=TableC.Field1
AND TableB.Field2=TableC.Field2);
WHERE
理由の詳細には立ち入らずに、このクエリを別の条件セットを使用した 3 つのテーブルのクロス結合として書き直すことができます。
SELECT TableA.Field1, TableB.Field2
FROM TableA, TableB, TableC WHERE
(TableA.Field1=TableC.Field1)
AND
(TableB.Field2<>TableC.Field2);
完全に同等のクエリ
この関係を元のクエリに適用すると、次のようになります。
SELECT Kalendar.id_kalendar, Os_udaje.Meno, Os_udaje.Priezvisko, Os_udaje.id_os_udaje
FROM Os_udaje, Kalendar, Pravocal, REZERVACIA, DOVOLENKA
WHERE ((((Kalendar.id_kalendar) Between [Pociatocný dátum] And [Koncový dátum])))
AND ((Kalendar.volno)=No)
AND ((Kalendar.vikend)=No)
AND (((Os_udaje.Nastupil)< Kalendar.id_kalendar ) AND ((Os_udaje.Odisiel)>Kalendar.id_kalendar))
AND (
Os_udaje.id_os_udaje = Pracoval.id_os_udaje
AND Kalendar.id_kalendar <> Pracoval.id_kalendar)
AND (
Kalendar.id_kalendar BETWEEN REZERVACIA.platnost_od AND REZERVACIA.platnost_do
AND Os_udaje.id_os_udaje <> REZERVACIA.id_os_udaje)
AND (
Kalendar.id_kalendar BETWEEN DOVOLENKA.od AND DOVOLENKA.do
AND Os_udaje.id_os_udaje <> DOVOLENKA.id_os_udaje);
パフォーマンスを向上させるためのヒント
このクエリは 5 つのテーブルのクロス結合を行っているため、非常に非効率的である可能性があります (それぞれの行数の積を取ります)。パフォーマンスを向上させる 2 つの手法は次のとおりです。
INNER JOIN
完全デカルト結合の代わりにステートメントを使用します。
SELECT * FROM
(SELECT * FROM Table1,Table2) As SubQry
INNER JOIN
Table3
ON (SubQry.Field2=Table3.Field2 AND SubQry.Field1<>Table3.Field1);
最初にサブクエリ条件を実行して、行数を減らします。
SELECT Kalendar2.id_kalendar, Os_udaje.Meno, Os_udaje.Priezvisko, Os_udaje.id_os_udaje
FROM Os_udaje,
(SELECT * FROM Kalendar
WHERE ((((Kalendar.id_kalendar) Between [Pociatocný dátum] And [Koncový dátum])))
AND ((Kalendar.volno)=No)
AND ((Kalendar.vikend)=No)) AS Kalendar2,
Pravocal,
...
可能な完全な答え
このクエリをテストすることはできず、BETWEEN
ステートメントがJOIN
条件として機能するかどうかもわかりませんが、結合とネストされたサブクエリを使用した答えは次のとおりです。
SELECT Kalendar.id_kalendar, Os_udaje.Meno, Os_udaje.Priezvisko, Os_udaje.id_os_udaje
FROM
(((
SELECT Kalendar.id_kalendar, Os_udaje.Meno, Os_udaje.Priezvisko, Os_udaje.id_os_udaje
FROM Os_udaje, Kalendar
WHERE ((((Kalendar.id_kalendar) Between [Pociatocný dátum] And [Koncový dátum])))
AND ((Kalendar.volno)=No)
AND ((Kalendar.vikend)=No)
AND (((Os_udaje.Nastupil)< Kalendar.id_kalendar ) AND ((Os_udaje.Odisiel)>Kalendar.id_kalendar))
) As SubQry
INNER JOIN
Pravocal
ON
(SubQry.id_os_udaje = Pracoval.id_os_udaje
AND SubQry.id_kalendar <> Pracoval.id_kalendar))
INNER JOIN
REZERVACIA
ON
(SubQry.id_kalendar BETWEEN REZERVACIA.platnost_od AND REZERVACIA.platnost_do
AND SubQry.id_os_udaje <> REZERVACIA.id_os_udaje))
INNER JOIN
DOVOLENKA
ON
(SubQry.id_kalendar BETWEEN DOVOLENKA.od AND DOVOLENKA.do
AND SubQry.id_os_udaje <> DOVOLENKA.id_os_udaje);