0

私はMSAccessdbアプリを作成しましたが、正しく動作します。

コンピューターとアクセスのバージョンを2007年から2010年に変更したい場合。クエリの結果を表示したい場合、エラーが表示されます。クエリを変更できますか、それとも他の間違いですか?

私の質問:

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)) 
AND ((NOT Exists (SELECT *
              FROM Pracoval
              WHERE Os_udaje.id_os_udaje = Pracoval.id_os_udaje
              AND Kalendar.id_kalendar = Pracoval.id_kalendar))) 
AND ((NOT Exists (SELECT *
              FROM REZERVACIA 
              WHERE Kalendar.id_kalendar BETWEEN REZERVACIA.platnost_od AND REZERVACIA.platnost_do 
              AND Os_udaje.id_os_udaje = REZERVACIA.id_os_udaje))) 
AND ((NOT Exists (SELECT *
              FROM DOVOLENKA 
              WHERE Kalendar.id_kalendar BETWEEN DOVOLENKA.od AND DOVOLENKA.do 
              AND Os_udaje.id_os_udaje = DOVOLENKA.id_os_udaje)));

エラー:

This expression is typed incorrectly, or it is too complex to be evaluated. For example, a numeric expression may contain too many complicated elements. Try simplifying the expression by assigning parts of the expression to variables. (Error 3071)
4

2 に答える 2

1

このクエリが 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);
于 2012-09-04T23:57:33.557 に答える
1

問題は、オペレーティング システムの設定にありました。データのフォーマットを「1.1.2012」にスペース付きで設定しており、スペースなしのアクセス形式「1.1.2012」で使用しています。Windowsで日付形式を変更すると、すべてが正しく機能し始めます。

于 2012-09-05T12:09:38.663 に答える