簡體   English   中英

查詢優化需要比較兩個日期的帳款余額[ADO MS-Access查詢]

[英]Query Optimization Needed to Compare A/c Balances at Two Dates [ADO MS-Access Query]

我想知道兩個不同日期結束時的余額差(余額比較)。

我在MS-Access 2003版本(DATABASE VERSION Access2000)中具有以下表結構:


積分

CreditID TxnDate PartyID TxnType金額注釋


借記

DebitID TxnDate PartyID TxnType金額注釋


派對

PartyID PartyName PartyAddress PartyContactNo描述

我使用VB6和ADO2運行下面的QUERY,以在兩個不同日期的末尾獲得“帳戶余額”,以進行比較。

SELECT P.PartyID, P.PartyName, 

IIF((SELECT SUM(C.Amount) FROM Credits C WHERE C.PartyID = P.PartyID AND C.TxnDate <= "#31/07/2014#") IS NULL,0,(SELECT SUM(C.Amount) FROM Credits C WHERE C.PartyID = P.PartyID AND C.TxnDate <= "#31/07/2014#"))
-
IIF((SELECT SUM(D.Amount) FROM Debits D WHERE D.PartyID = P.PartyID AND D.TxnDate <= "#31/07/2014#") IS NULL, 0, (SELECT SUM(D.Amount) FROM Debits D WHERE D.PartyID = P.PartyID AND D.TxnDate <= "#31/07/2014#")) AS BalanceOn31Jul2014, 

IIF((SELECT SUM(C.Amount) FROM Credits C WHERE C.PartyID = P.PartyID AND C.TxnDate <= "#31/08/2014#") IS NULL, 0, (SELECT SUM(C.Amount) FROM Credits C WHERE C.PartyID = P.PartyID AND C.TxnDate <= "#31/08/2014#"))
-
IIF((SELECT SUM(D.Amount) FROM Debits D WHERE D.PartyID = P.PartyID AND D.TxnDate <= "#31/08/2014#") IS NULL, 0, (SELECT SUM(D.Amount) FROM Debits D WHERE D.PartyID = P.PartyID AND D.TxnDate <= "#31/08/2014#")) AS BalanceOn31Aug2014 

FROM Parties AS P

ORDER BY PartyName;

上面的查詢運行,但是非常慢。

我想知道是否仍然可以優化上述“ QUERY”?

我認為使用group by一次性計算所有貸方和借方會更快:

select
    c.PartyID,
    c.PartyName,
    Nz(c.Credit31Jul2014, 0) - Nz(d.Debit31Jul2014, 0) as BalanceOn31Jul2014,
    Nz(c.Credit31Aug2014, 0) - Nz(d.Debit31Aug2014, 0) as BalanceOn31Aug2014
from (
    select
        p.PartyID,
        p.PartyName,
        sum(iif(c.TxnDate <= #31/07/2014#, c.amount, 0)) as Credit31Jul2014,
        sum(iif(c.TxnDate <= #31/08/2014#, c.amount, 0)) as Credit31Aug2014
    from
        Parties p
            left outer join
        Credits c
            on p.PartyID = c.PartyID
    group by
        p.PartyID,
        p.PartyName
    ) c left outer join (
    select
        d.PartyID,
        sum(iif(d.TxnDate <= #31/07/2014#, d.amount, 0)) as Debit31Jul2014,
        sum(iif(d.TxnDate <= #31/08/2014#, d.amount, 0)) as Debit31Aug2014
    from
        Debits d
    where
        d.TxnDate <= #31/08/2014#
    group by
        d.PartyID
    ) d on c.PartyID = d.PartyID
order by
    c.PartyName;

您可能需要考慮存儲一個余額表,該表可以在各個日期(例如每月一次)保持聚會余額。 那將限制您必須求和的時間間隔。

看看為什么快。 首先,對於您的查詢,您基本上在運行至少4個,每個PartyID可能有8個選擇。 您可以使用Nz(sum(xxx), 0)而不是Iif(sum(xxx) is null, 0, sum(xxx))稍微簡化Iif(sum(xxx) is null, 0, sum(xxx)) 這樣只能保證4。這些選擇中的每一個都需要讀取整個貸方或借方表。 現在,單獨考慮查詢的這一部分:

select
    d.PartyID,
    sum(iif(d.TxnDate <= #31/07/2014#, d.amount, 0)) as Debit31Jul2014,
    sum(iif(d.TxnDate <= #31/08/2014#, d.amount, 0)) as Debit31Aug2014
from
    Debits d
where
    d.TxnDate <= #31/08/2014#
group by
    d.PartyID

這將獲得每一方的總借方。 想象得到一個分類帳並被要求進行計算。 您將使用筆記本來保留部分結果。 如果每個分類帳項目都符合您在記事本中查找的日期標准,以查看您是否有此聚會的記錄,則您將依次閱讀。 如果沒有,您將在行中添加一個。 如果您這樣做,則將金額替換為金額加上該行中的金額。 要意識到的關鍵是,您只需閱讀一次分類帳就可以完成所有這些工作。 使用您的方法,您每方要多次讀取分類帳。

我在代碼的第4行和第5行中修改了Laurence對AVOID Nz / IIf的回答。

感謝Laurance,沒有他,我現在無法回答這個問題。

因此,我使用的最終代碼是

SELECT cc.PartyID, cc.PartyName,
       (cc.Credit31Jul2014 - dd.Debit31Jul2014) AS BalanceOn31Jul2014,
       (cc.Credit31Aug2014 - dd.Debit31Aug2014) AS BalanceOn31Aug2014
FROM
   (SELECT p.PartyID, p.PartyName,
        SUM(IIF(c.TxnDate <= #31/07/2014#, c.amount, 0)) AS Credit31Jul2014,
        SUM(IIF(c.TxnDate <= #31/08/2014#, c.amount, 0)) AS Credit31Aug2014
    FROM Parties p
    LEFT OUTER JOIN Credits c ON p.PartyID = c.PartyID
    GROUP BY p.PartyID, p.PartyName) AS cc
LEFT OUTER JOIN
   (SELECT p.PartyID,
        SUM(IIF(d.TxnDate <= #31/07/2014#, d.amount, 0)) AS Debit31Jul2014,
        SUM(IIF(d.TxnDate <= #31/08/2014#, d.amount, 0)) AS Debit31Aug2014
    FROM Parties p
    LEFT OUTER JOIN Debits d ON p.PartyID = d.PartyID
    GROUP BY p.PartyID) AS dd
ON dd.PartyID = cc.PartyID
ORDER BY cc.PartyName;

感謝Laurence @Laurence

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM