2013-02-12 74 views
0

這是運行速度非常慢的MS Access查詢。 Results表是主表,而PB,SC表是子表。列組合IndexResultID在所有這些表中都是獨一無二的。因此,例如,表C中只能有一行,其中Index爲「1」,ResultID爲2.我沒有使用JOIN,因爲MS Access只支持內部連接,而我需要的是外部連接,因爲我即使在任何其他表中沒有對應的記錄,也希望顯示錶Results中的所有記錄。在MS ACCESS查詢中優化一堆嵌套SELECTs

SELECT 
    [Results].[Id], 
    [Results].[Name], 
    [Results].[OfferPrice], 
    [Results].[RegPrice], 
    [Results].[ImageFileName], 
    [Results].[Image], 
    [Results].[URL], 
    (SELECT P.P FROM P WHERE P.ResultID = Results.Id AND P.Index = "0") as P0, 
    (SELECT P.P FROM P WHERE P.ResultID = Results.Id AND P.Index = "1") as P1, 
    (SELECT P.P FROM P WHERE P.ResultID = Results.Id AND P.Index = "2") as P2, 
    (SELECT P.P FROM P WHERE P.ResultID = Results.Id AND P.Index = "3") as P3, 
    (SELECT P.P FROM P WHERE P.ResultID = Results.Id AND P.Index = "4") as P4, 
    (SELECT P.P FROM P WHERE P.ResultID = Results.Id AND P.Index = "5") as P5, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "0") as B0, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "1") as B1, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "2") as B2, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "3") as B3, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "4") as B4, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "5") as B5, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "6") as B6, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "7") as B7, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "8") as B8, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "9") as B9, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "10") as B10, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "11") as B11, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "12") as B12, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "13") as B13, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "14") as B14, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "15") as B15, 
    (SELECT B.B FROM B WHERE B.ResultID = Results.Id AND B.Index = "16") as B16, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "1") as S1, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "2") as S2, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "3") as S3, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "4") as S4, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "5") as S5, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "6") as S6, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "7") as S7, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "8") as S8, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "9") as S9, 
    (SELECT S.S FROM S WHERE S.ResultID = Results.Id AND S.Index = "10") as S10, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "0") as C0, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "1") as C1, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "2") as C2, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "3") as C3, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "4") as C4, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "5") as C5, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "6") as C6, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "7") as C7, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "8") as C8, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "9") as C9, 
    (SELECT C.C FROM C WHERE C.ResultID = Results.Id AND C.Index = "10") as C10 
FROM 
    Results 
+2

什麼讓你相信Access不支持外連接? – Brad 2013-02-12 16:25:29

回答

4

我不知道你在哪裏得到如下:

我沒有使用JOIN,因爲MS Access只支持內部連接和什麼我需要的是一個外部聯接

MS Access支持OUTER JOIN syntax

您可以用每個表格之間的LEFT JOIN替換您的相關子查詢。您的代碼將與此類似:

SELECT 
    [Results].[Id], 
    [Results].[Name], 
    [Results].[OfferPrice], 
    [Results].[RegPrice], 
    [Results].[ImageFileName], 
    [Results].[Image], 
    [Results].[URL], 
    max(IIF(P.Index = "0", P.P, null)) as P0, 
    max(IIF(P.Index = "1", P.P, null)) as P1, 
    max(IIF(P.Index = "2", P.P, null)) as P2, 
    max(IIF(P.Index = "3", P.P, null)) as P3, 
    max(IIF(P.Index = "4", P.P, null)) as P4, 
    max(IIF(P.Index = "5", P.P, null)) as P5, 
    max(IIF(B.Index = "0", B.B, null)) as B0, 
    max(IIF(B.Index = "1", B.B, null)) as B1, 
    max(IIF(B.Index = "8", B.B, null)) as B8, 
    max(IIF(S.Index = "2", S.S, null)) as S2, 
    max(IIF(C.Index = "1", C.C, null)) as C1 
FROM Results 
LEFT JOIN P 
    on P.ResultID = Results.Id 
LEFT JOIN B 
    on B.ResultID = Results.Id 
LEFT JOIN S 
    on S.ResultID = Results.Id 
LEFT JOIN C 
    on C.ResultID = Results.Id 
GROUP BY [Results].[Id], 
    [Results].[Name], 
    [Results].[OfferPrice], 
    [Results].[RegPrice], 
    [Results].[ImageFileName], 
    [Results].[Image], 
    [Results].[URL] 

你也應該能夠使用TRANSFORM函數的數據,代碼將類似於此:

TRANSFORM Max(Src.Value) 
select 
    [Results].[Id], 
    [Results].[Name], 
    [Results].[OfferPrice], 
    [Results].[RegPrice], 
    [Results].[ImageFileName], 
    [Results].[Image], 
    [Results].[URL] 
from results as R 
left join 
(
    select ResultID, P as Value, "P"&Index as col 
    from p 
    union all 
    select ResultID, B as Value, "B"&Index as col 
    from B 
    union all 
    select ResultID, C as Value, "C"&Index as col 
    from C 
    union all 
    select ResultID, S as Value, "S"&Index as col 
    from S 
) as Src 
    on R.id = Src.ResultID 
GROUP BY [Results].[Id], [Results].[Name], 
    [Results].[OfferPrice],[Results].[RegPrice], 
    [Results].[ImageFileName], [Results].[Image], 
    [Results].[URL] 
PIVOT Src.col 
+0

爲什麼這個組合?我不認爲這是必要的。 – 2013-02-12 16:29:43

+2

@ypercube有一個聚合函數 – Taryn 2013-02-12 16:30:24

+0

對不起,沒有注意到。如果你把'Index ='0''條件放在'ON'子句中,你就不需要GROUP BY或聚合,對嗎? – 2013-02-12 16:31:35

1

如果使連接明確,則查詢運行得更快。這裏是模板:

SELECT 
    [Results].[Id], 
    [Results].[Name], 
    [Results].[OfferPrice], 
    [Results].[RegPrice], 
    [Results].[ImageFileName], 
    [Results].[Image], 
    [Results].[URL], 
    max(iif(p.index = "0", p.p, "")) as p0, 
    . . . 
FROM results left outer join 
    p 
    on results.id = p.resultid left outer join 
    . . . 
group by [Results].[Id], 
    [Results].[Name], 
    [Results].[OfferPrice], 
    [Results].[RegPrice], 
    [Results].[ImageFileName], 
    [Results].[Image], 
    [Results].[URL] 

的想法是使用left outer join表中,使加入他們在正確的條件和使用聚合收縮他們回到每個結果一行。 SELECT中的邏輯根據您設置的邏輯選擇值。

1

這應該蠻運行很快。它看起來像你試圖對一個表和多個表的聯合之間的連接做一個關鍵點。下面的unionized表替換您的所有連接。事實上,這是pivoted取代了需要做任何相關的子查詢。

TRANSFORM Max(unionized.DataColumn) AS MaxOfDataColumn 
SELECT Results.ResName, Results.OfferPrice, Results.RegPrice, Results.Image, Results.URL 
FROM (
    Select B.ID, B.B as DataColumn, "B"&B.B as tableName from B 
    union all select C.ID, C.C, "C"&C.C from C 
    union all select P.ID, P.P, "P"&P.P from P 
    union all select S.ID, S.S, "S"&S.S from S) AS unionized 
RIGHT JOIN Results ON unionized.ID = Results.ID 
GROUP BY Results.ResName, Results.OfferPrice, Results.RegPrice, Results.Image, Results.URL 
PIVOT unionized.tableName; 

您需要清理一下,因爲我假設您使用了示例列,但希望您明白這一點。