0

SQLデータベースで実行すると次の結果を出力するクエリがあります

CreatedDate                 QuoteNumber NumberOfLicensedDrivers
2012-07-01 10:38:49.157 48641           0
2012-07-01 18:35:38.680 48650           2
2012-07-02 08:44:33.770 48670           1
2012-07-02 09:12:09.447 48700           0

この投稿のためにクエリを簡略化しましたが、基本的には次のとおりです。

SELECT DISTINCT
       CreatedDate,
       QuoteNumber,
       count([DriversLicense]) as NumberOfLicensedDrivers
FROM table1 LEFT OUTER JOIN table2 on table2.QuoteID = table1.ID 
WHERE CreatedDate > '7/1/2012'
GROUP BY QuoteNumber, CreatedDate 
ORDER BY CreatedDate ASC

このクエリにより、期待される出力が得られます。すべての引用符を出力に表示したいと思います。ドライバーが0の場合、0を表示したいと思います。問題は、リンクされたテーブルを使用したMSアクセスで同じ結果を作成する必要があることです。MS Accessの出力では、期待した結果が得られません。

これが私がMSACCESSに使用するクエリです

SELECT DISTINCT 
     quote.CreatedDate, 
     quote.QuoteNumber, 
     count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
FROM quote 
LEFT JOIN quoteDrivers ON quote.ID = quoteDrivers.QuoteID
WHERE (quote.CreatedDate>#7/1/2012#)
GROUP BY quote.CreatedDate, quote.QuoteNumber
ORDER BY quote.CreatedDate;

出力には、ライセンスされたドライバーは表示されません。

CreatedDate            QuoteNumber  NumberOfLicensedDrivers
7/1/2012 10:38:49 AM   48641    0
7/1/2012 6:35:39 PM    48650    0
7/2/2012 8:44:34 AM    48670    0
7/2/2012 9:12:09 AM    48700    0

ただし、quoteDriversテーブルに対してWHERE句を追加すると、次のようになります。

SELECT DISTINCT 
    quote.CreatedDate, 
    quote.QuoteNumber, 
    count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
FROM quote 
LEFT JOIN quoteDrivers ON quote.ID = quoteDrivers.QuoteID
WHERE (quote.CreatedDate>#7/1/2012#)
and quoteDrivers.DriverAddedDate >#1/1/2012# ''Added this
GROUP BY quote.CreatedDate, quote.QuoteNumber
ORDER BY quote.CreatedDate;

期待どおりの結果が得られます(ドライバーが0の場合の見積もりを差​​し引いたもの)

CreatedDate         QuoteNumber NumberOfLicensedDrivers
7/1/2012 6:35:39 PM 48650           2
7/2/2012 8:44:34 AM 48670           1

quoteDriversテーブルのwhere句に列を指定せずにドライバーの数を取得できない理由を誰かが説明できますか?

4

4 に答える 4

1

Accessがこれをサポートしているかどうかはわかりませんが、一般的なSQLでは、条件を結合のon句に移動すると、クエリの「外部」部分が機能し続けます。

Select
  quote.CreatedDate, 
  quote.QuoteNumber, 
  count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
From
  quote 
    Left Join
  quoteDrivers 
    On quote.ID = quoteDrivers.QuoteID And quoteDrivers.DriverAddedDate > #1/1/2012#
Where
  quote.CreatedDate > #7/1/2012#
Group By
  quote.CreatedDate, 
  quote.QuoteNumber
Order By
  quote.CreatedDate;

また、あなたの区別は、このグループによって不要です。おそらくオプティマイザーは遅くならないほど賢いのですが、なぜチャンスをつかむのですか?

于 2012-12-11T21:00:39.480 に答える
1

1つの特定の修正:結合サーバー側をカプセル化するSQLサーバー上にビューを作成し、Accessでリンクテーブルとしてビューにリンクすることができます。また、日付変数ロジックを確認し、それをDateDiff関数に置き換えて、ハードコードされた日付リテラルがローカル設定に従って異なる方法で解釈される問題を回避してください。

于 2012-12-11T21:07:02.597 に答える
1

次のようにクエリを書き直すことをお勧めします。

SELECT CreatedDate, QuoteNumber, Count(*) as NumberOfLicensedDrivers
FROM (
    SELECT q.CreatedDate, q.QuoteNumber, qd.DriversLicense
    FROM quote q INNER JOIN quoteDrivers qd ON q.ID = qd.QuoteID
    WHERE q.CreatedDate > #7/1/2012#
) X
GROUP BY CreatedDate, QuoteNumber
ORDER BY 1

サブクエリ内のテーブルを組み合わせて、これからドライバーの数を取得することにより、クエリフォームはMSSQLサーバーSQLとMSJet SQL(MSアクセスSQL)の両方のルールセットに適合し、したがって、msアクセスの範囲が狭くなります。 「何か間違っている」ことを実行すると、結果セットは同じになります。

日付形式#..#については本当によくわかりません。SQLでは、これは通常'..'です。バックエンドが別のmsaccessdbの場合、形式#..#は必須ですが、SQLの場合、「..」の方がうまくいく可能性があります。ただし、特定のオフハンドについては言えないので、これをテストすることをお勧めします。

お役に立てれば :-)

于 2012-12-12T03:55:25.630 に答える
0

私の愚かさは私を捕まえた。次のクエリが機能した理由がわかりません。

SELECT DISTINCT 
    quote.CreatedDate, 
    quote.QuoteNumber, 
    count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
FROM quote 
LEFT JOIN quoteDrivers ON quote.ID = quoteDrivers.QuoteID
WHERE (quote.CreatedDate>#7/1/2012#)
and quoteDrivers.DriverAddedDate >#1/1/2012# 
GROUP BY quote.CreatedDate, quote.QuoteNumber
ORDER BY quote.CreatedDate;

quoteDrivers.QuoteIDは文字列であり、quote.IDはGUIDです。リンクテーブルを作成する場合、MSAccessはGUIDの前後に角かっこ{}を追加します。quoteDriversテーブルに対してwhere句を追加した場合にのみクエリが機能する理由がわかりません。

次のクエリは、私が必要としているものを正確に示しています。

SELECT DISTINCT 
    quote.CreatedDate, 
    quote.QuoteNumber, 
    count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
FROM quote 
LEFT JOIN quoteDrivers ON quote.ID = "{" + quoteDrivers.QuoteID + "}"
WHERE (quote.CreatedDate>#7/1/2012#)
GROUP BY quote.CreatedDate, quote.QuoteNumber
ORDER BY quote.CreatedDate;

カラムの構造を事前に説明しておけばよかったので、説明しなくてすみません。quoteDriversテーブルに対してwhere句を追加したときに、結合が機能する理由を誰かが説明できれば、("and quoteDrivers.DriverAddedDate >#1/1/2012#")本当にありがたいです。

于 2012-12-12T14:15:00.137 に答える