[英]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
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]);
子查詢創建一個名為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.