簡體   English   中英

使用嵌套子查詢優化MS ACCESS SQL

[英]Optimize MS ACCESS SQL with Nested Sub-Queries

問題

我正在一個MS Access數據庫中,該數據庫將發票中的條目轉換為會計總帳代碼。 數據庫有時會“拆分”記錄(例如,包含單個費用的發票可能需要將該費用分配給多個不同的業務部門)。 我已經編寫了一個SQL查詢,以使用INSERT INTO查詢將“拆分”記錄插入數據庫表后刪除“父”記錄。 不幸的是,我主要是通過反復試驗來編寫此程序,並且它運行得非常慢(我相信這是嵌套子查詢的結果)。

我該怎么做才能優化此查詢?

數據庫插圖

作為說明,如果一個表包含以下內容:
[類型] ---- [收費] ---- [說明] ------------------- [發票金額]
5000 ------ NoDept ------ 40 SQL頭盔-------------- $ 500

該記錄的拆分可能類似於:
[類型] ---- [收費] ---- [說明] ------------------- [發票金額]
5000 ------ NoDept ------ 40 SQL頭盔-------------- $ 500
5000 ------ NoDept ------ 40 SQL頭盔_%分裂---- $ 200
5000 ------ NoDept ------ 40 SQL頭盔_%分裂---- $ 75
5000 ------ NoDept ------ 40 SQL頭盔_%分裂---- $ 225

在我的SQL語句清理表之后,應該像這樣保留它:
[類型] ---- [收費] ---- [說明] ------------------- [發票金額]
5000 ------ NoDept ------ 40 SQL頭盔_%分裂---- $ 200
5000 ------ NoDept ------ 40 SQL頭盔_%分裂---- $ 75
5000 ------ NoDept ------ 40 SQL頭盔_%分裂---- $ 225

當前SQL

DELETE * 
FROM [tblManipulateW] 
WHERE EXISTS 
    (SELECT * FROM 
        (SELECT SUM([Dupe].[Invoice Amount]) AS [SumInvoices], 
    [Dupe].[Type], 
        [Dupe].[Charge], 
        LEFT([Dupe].[Description], Len([Dupe].[Description]) - 7) As DescriptionLessSplit 
        FROM [tblManipulateW] AS [Dupe] 
        GROUP BY [Dupe].[Type], 
        [Dupe].[Charge], 
        LEFT([Dupe].[Description], LEN([Dupe].[Description])-7), 
        [Dupe].[Description] LIKE "*_%Split"
        HAVING [Dupe].[Description] LIKE "*_%Split") AS [Dupe2] 
    WHERE [Dupe2].[DescriptionLessSplit] = [tblManipulateW].[Description] 
    AND [Dupe2].[Type] = [tblManipulateW].[Type] 
    AND ROUND([Dupe2].[SumInvoices],2) = ROUND([tblManipulateW].[Invoice Amount],2) 
    AND [Dupe2].[Charge] = [tblManipulateW].[Charge]);

SQL說明

子查詢創建一個名為Dupe2的查詢,該查詢查找已拆分的所有相同費用並返回:
-發票金額之和
-他們的描述減去短語“ _%Split”
-他們的收費代碼
-他們的類型代碼

子查詢正在檢查主表中的項目是否與子查詢又稱為Dupe2返回的項目匹配。 如果條目確實與每個字段匹配,則將其刪除。

非常感謝您對此進行查看!

我建議向您的tblManipulateW表中再增加兩列:自動增量主鍵( ID )和ParentID列(可以為null ),以便拆分可以有選擇地標識其父級。 這就是為什么。

假設您有這樣一個主鍵。 而假設你的'40 SQL盔為$ 500項原本具有ID 25.現在,當你做你的日常分裂,而不是追加一些文字的Description ,實際上你可以設置ParentID為所有的孩子分裂到25現在,您可以輕松找到所有父拆分-它們都是有孩子的拆分:

select t1.*
from tblManipulateW as t1
inner join tblManipulateW as t2
on t1.ID = t2.ParentID

此查詢非常容易優化-實際上,如果將ID列設置為自動增量主鍵,則Access會自動為您執行此查詢。 而且還有一個好處,就是數據比以前更規范了(您將父子關系存儲在單獨的列中,而不是在Description列中添加了一些文本)。

附錄:您可以執行一個更重要的優化:使ParentID列成為引用ID列的外鍵。 以下應該可以做到這一點: *

alter table tblManipulateW
add column ParentID long
constraint ManipulateW_ParentID
references tblManipulateW (ID)
on delete set null;

上面全面介紹了ParentID列。 最后一行( on delete set null )是可選的; 它僅通過將拆分中的ParentID值自動設置為null如果刪除了父拆分)來幫助保留參照完整性。

ParentID為外鍵的好處是Access會將其實現為數據庫中的索引,這將自動加快我之前顯示的聯接。

*請注意,此SQL使用ANSI-92語法,在Access“前端” SQL編輯器中不支持該語法。 您將需要使用一些VBA來執行它: CurrentProject.Connection.Execute "alter table ..."

暫無
暫無

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

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