0

SQL を実装する Access プロジェクトがあり、調整プロセスの最適化に取り組んでいます。このプロセスでは、すべてのテーブルをリンクするバウチャー システムが使用されます。各テーブルの各レコードには、金額が関連付けられている特定の伝票 ID があります。バウチャー自体は一意であり、以下に示す複数のバウチャー番号を含めることができます。

Table: Rec_Vouchers
v_id       v_num      voucher
1          12341234   12341234
2          10101010   10101010;22222222
2          22222222   10101010;22222222
...

これらのバウチャー ID によってリンクされている他の 8 つのテーブルがあります。すべてのテーブルを結合して、個別のバウチャー ID とバウチャー、およびその特定のバウチャー ID を持つ各テーブルの対応する金額の合計をすべて表示しようとしています。以下は、クエリと結果のサンプルです。私はこれにしばらく取り組んできましたが、頭が痛くなり始めています。このクエリは機能しますが、実行に時間がかかります。

また、ある時点で、これらの値をすべて照合して、バウチャーが「一致する」、「一致しない」、または「一致して差がある」かどうかを判断する必要があります。これまでのところ、各バウチャーの列に表示する "M"、"NM"、または "MwD" の文字列値を返す関数を以下のコード内で作成しようとしただけです。繰り返しますが、これは機能しますが、非常に長い時間がかかります。また、クエリから返されたレコードセットで VBA に汚い作業をさせようとしましたが、これにもかなりの時間がかかりますが、SQL クエリ内で関数を作成するほどではありません。これは次のステップなので、このすべてを手伝ってくれるならそれは素晴らしいことですが、私が本当に必要としているのは、与えられたクエリを最適化することだけです。

これはあなたの頭を包み込むことがたくさんあることを知っているので、さらに情報が必要な場合はお知らせください. どんな助けでも大歓迎です。ありがとう!

select a.v_id, a.voucher,
(Select sum(b.amount) from rec_month_4349_test b where b.voucher = a.v_id) as GL, 
(Select sum(c.payments) from rec_daily_balancing_test c where c.voucher = a.v_id) as DB,
(Select count(x.v_num) from rec_vouchers x where a.v_id = x.v_id and x.v_num not like 'ONL%') as GLcount,
(select count(c.batch_num) from rec_daily_balancing_test c where a.v_id = c.voucher) as DBcount,
(select sum(d.amount) from rec_ed_test d where a.v_id = d.voucher) as ED, 
(select sum(e.batchtotal) from rec_eft_batches_new_test e where a.v_id = e.voucher) as EFT, 
(select sum(f.batchtotal) from rec_check_batch_test f where a.v_id = f.voucher) as CHK, 
(select sum(g.idxtotal) from rec_lockbox_test g where a.v_id = g.voucher) as LBX, 
(select sum(h.amount) from rec_lcdl_test h where a.v_id = h.voucher) as LCDL, 
((select sum(i.payment_amount) from rec_electronic_files_test i where a.v_id = i.voucher) + (select sum(j.amount) from rec_electronic_edits_test j where a.v_id = j.voucher)) as Elec
from rec_vouchers a
group by a.v_id, a.voucher

Sample Results:
v_id     GL         DB         GLcount   DBcount     ED     EFT     CHK     LBX     LCDL     Elec
6131     19204.00   19204.00   1         1           NULL   NULL    NULL    NULL    NULL     NULL
6132     125330.00  14932.00   6         6           NULL   NULL    NULL    NULL    NULL     14932.00
6133     18245.00   NULL       2         0           NULL   NULL    NULL    NULL    NULL     NULL
6175     98.93      98.93      1         1           NULL   98.93   NULL    NULL    NULL     NULL 
4

3 に答える 3

0

このクエリを記述する "従来の" 方法は、述語fromを使用してテーブルを句に移動することだと言いたくなるかもしれません。joinただし、それはおそらく不要なデカルト積を導入するでしょう。あなたの方法は実際には問題ありません。別の方法はleft join、集約されたサブクエリに対して s を実行することです。

パフォーマンスのキラーは、おそらくテーブルを循環して一致を見つけることによるものです。where各クエリの句で使用されるフィールドにインデックスを付けることで、パフォーマンスを大幅に向上させることができます。たとえば、最初の 2 つのテーブルについては、 と にインデックスが必要rec_month_4349_test(voucher)ですrec_daily_balancing_test(voucher)

SQL Server では、合計に使用される変数をインデックスにも含めることで、このクエリをさらに最適化できます。次のインデックスの方が適切です: rec_month_4349_test(voucher, amount)and rec_daily_balancing_test(voucher, payments)(または、検索可能にせずにインデックスに含めることができます。これは、もう少し高度です)。

この最適化は、ほとんどのデータベースで機能します (インデックス ルックアップではなくインデックス スキャン)。MS Access (可能な限り避けようとしているソフトウェア製品) で動作するかどうかはわかりません。

すべてのテーブルに対してこれを行う必要があることに注意してください。

于 2013-10-29T22:31:22.523 に答える
0

これが最善の解決策かどうかはわかりませんが、テーブルごとに個別のビューを作成して、バウチャーと特定のバウチャーごとの金額の合計を選択しました。各ビューは次のように見えます。

rec_sum4349

SELECT voucher, sum(amount) AS GL
FROM rec_month_4349_test
GROUP BY voucher

次に、次のような完全な結合を使用して、個別のビューをすべて結合する 1 つのビューを作成します。

rec_vouch_test

SELECT a.voucher, a.GL, b.DB
FROM rec_sum4349 a
FULL JOIN rec_sumDB b
ON a.voucher = b.voucher
WHERE a.voucher IS NOT NULL AND a.voucher <> ''
ORDER BY a.voucher

これがうまく機能することを確認した後、合計金額が必要な残りのテーブルのビューを作成し、それらを上記のビューに追加しました。結果はまさに私が探していたもので、実行時間はほぼ 2 分から数秒に短縮されました! すべての助けをありがとう。さあ、すべてを合わせましょう!

于 2013-10-30T15:58:10.783 に答える