简体   繁体   中英

How to optimize the query using join with a subquery?

I want to be able to list the sum of the st.balancechange, but for different s.type. It is taking the query about 7 minutes to run. I'm sure there is a better way to optimize it, but I'm not sure how. I can't use it as a sub query, because I need to return more than one result.

SELECT DISTINCT a.ACCOUNTNUMBER AS [Account Number]
    , s1.Deposit AS [Aggregate Share Balance]
    , c.Deposit AS [Aggregate Checking Balance]

FROM dbo.ACCOUNT a

JOIN dbo.SAVINGS s
    ON a.ACCOUNTNUMBER = s.PARENTACCOUNT
        AND a.ProcessDate = s.ProcessDate

JOIN (SELECT a.ACCOUNTNUMBER
    , SUM(st.BALANCECHANGE) AS [Deposit]
FROM dbo.ACCOUNT a
JOIN dbo.SAVINGS s
    ON a.ACCOUNTNUMBER = s.PARENTACCOUNT
        AND a.ProcessDate = s.ProcessDate
JOIN dbo.SAVINGSTRANSACTION st
    ON st.PARENTACCOUNT = s.PARENTACCOUNT
WHERE a.ProcessDate = CONVERT(VARCHAR(8), DATEADD(DAY,-1, GETDATE()), 112)
    AND a.CLOSEDATE IS NULL
    AND s.CLOSEDATE IS NULL 
    AND st.ACTIONCODE = 'D'
    AND s.TYPE IN (0, 1, 2, 3, 4, 6, 100)
    GROUP BY a.ACCOUNTNUMBER) s1 ON s1.ACCOUNTNUMBER = a.ACCOUNTNUMBER

LEFT JOIN (SELECT a.ACCOUNTNUMBER
    , SUM(st.BALANCECHANGE) AS [Deposit]
FROM dbo.ACCOUNT a
JOIN dbo.SAVINGS s
    ON a.ACCOUNTNUMBER = s.PARENTACCOUNT
        AND a.ProcessDate = s.ProcessDate
JOIN dbo.SAVINGSTRANSACTION st
    ON st.PARENTACCOUNT = s.PARENTACCOUNT
WHERE a.ProcessDate = CONVERT(VARCHAR(8), DATEADD(DAY,-1, GETDATE()), 112)
    AND a.CLOSEDATE IS NULL
    AND s.CLOSEDATE IS NULL 
    AND st.ACTIONCODE = 'D'
    AND s.TYPE IN (2, 100, 101, 102, 103, 104, 105, 106, 107, 108, 113, 150, 201)
    GROUP BY a.ACCOUNTNUMBER) c ON c.ACCOUNTNUMBER = a.ACCOUNTNUMBER

WHERE a.ProcessDate = CONVERT(VARCHAR(8), dateadd(day,-1, getdate()), 112)
    AND a.CLOSEDATE IS NULL
    AND s.CLOSEDATE IS NULL 
ORDER BY a.ACCOUNTNUMBER

Current results:

Account Number  Aggregate Share Balance   Aggregate Checking Balance
0000001234           7383.58                      NULL
0000001235           95856.83                   95856.83
0000001236            123.27                     123.27
0000001237             1.88                       NULL
0000001238           14812.26                     NULL
0000001239            15.00                       NULL
0000001240            4.06                        NULL
0000001241            6.42                        3.21
0000001242           3705.03                    3705.03
0000001243          976841.06                  1465261.59

I don't think you need to query for balances two times. The only difference between the two subqueries is TYPE. You can try something similar to below and only query once. I also think the DISTINCT is unnecessary as you can group your main query by account number if you remove the sub-queries.

SELECT a.ACCOUNTNUMBER AS [Account Number],
    SUM(CASE WHEN s.TYPE IN (0, 1, 2, 3, 4, 6, 100) THEN st.BALANCECHANGE ELSE NULL END) AS [Aggregate Share Balance],
    SUM(CASE WHEN s.TYPE IN (2, 100, 101, 102, 103, 104, 105, 106, 107, 108, 113, 150, 201) THEN st.BALANCECHANGE ELSE NULL END) AS [Aggregate Share Balance]
FROM dbo.ACCOUNT a
JOIN dbo.SAVINGS s ON a.ACCOUNTNUMBER = s.PARENTACCOUNT AND a.ProcessDate = s.ProcessDate
LEFT OUTER JOIN dbo.SAVINGSTRANSACTION st ON st.PARENTACCOUNT = s.PARENTACCOUNT
WHERE
    a.ProcessDate = CONVERT(VARCHAR(8), dateadd(day,-1, getdate()), 112)
    AND a.CLOSEDATE IS NULL
    AND s.CLOSEDATE IS NULL
GROUP BY
    a.ACCOUNTNUMBER
ORDER BY 
    a.ACCOUNTNUMBER  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM