2016-09-22 74 views
0

我寫了一個難以閱讀的查詢,我擔心效率可能不好。根據從每個表到consumerdata.consumerid的消息匹配,可以更有效地編寫此查詢嗎?左連接 - 如何更高效?

select 

consumerdata.consumerid, 
signupdate, 
city, 
state, 
year(DOB), 
topaffiliate, 
activestatus, 
lastuseddate, 

(select sum(achload.transactionamount) from achload where achload.consumerid = consumerdata.consumerid) as Total_ACH, 
(select sum(billpay.transactionamount) from billpay where billpay.consumerid = consumerdata.consumerid) as Bill_Pay, 
(select sum(recharge.transactionamount) from recharge where recharge.consumerid = consumerdata.consumerid) as Revenue, 
(select count(cash.consumerid) from Cash where cash.consumerid = consumerdata.consumerid) as Cash__TXNs, 
(select sum(moneytransfer.transactionamount) from moneytransfer where moneytransfer.consumerid = consumerdata.consumerid) as Transfer, 
(select sum(moneytransfer.commissionfeeamount) from moneytransfer where moneytransfer.consumerid = tbl_accounts_consumerdata.consumerid) as commission_fee, 
(select count(interchangetransactions.transactiondescription) from interchangetransactions where interchangetransactions.transactiondescription = "Withdrawal" and interchangetransactions.consumerid = consumerdata.consumerid) as Withdrawals, 
(select count(interchangetransactions.responsecode) from interchangetransactions where interchangetransactions.responsecode in (01) and interchangetransactions.consumerid = consumerdata.consumerid and interchangetransactions.transactiondescription = "Withdrawal") as Code_01, 
(select count(interchangetransactions.responsecode) from interchangetransactions where interchangetransactions.responsecode in (02) and interchangetransactions.consumerid = consumerdata.consumerid and interchangetransactions.transactiondescription = "Withdrawal") as Code_02, 
(select count(interchangetransactions.transactiondescription) from interchangetransactions where interchangetransactions.transactiondescription IN ("2 Cash Advance", "1 Cash Advance") and interchangetransactions.consumerid = consumerdata.consumerid) as Cash_Advance_Count, 
(select count(interchangetransactions.transactiondescription) from interchangetransactions where interchangetransactions.transactiondescription IN ("Balance") and interchangetransactions.consumerid = consumerdata.consumerid) as Inquiry_Count, 
(select sum(interchangetransactions.transactionamount) from interchangetransactions where interchangetransactions.transactiontypecode = 195 and interchangetransactions.consumerid = consumerdata.consumerid) as Intnl_TXN_Sum, 
(select count(interchangetransactions.transactionamount) from interchangetransactions where interchangetransactions.transactiontypecode = 195 and interchangetransactions.consumerid = consumerdata.consumerid) as Intnl_TXN_Count 


from 
consumerdata 

left join achload 
on achload.consumerid=consumerdata.consumerid 

left join billpay 
on billpay.consumerid = consumerdata.consumerid 

left join recharge 
on recharge.consumerid = consumerdata.consumerid 

left join cash 
on cash.consumerid = consumerdata.consumerid 

left join moneytransfer 
on moneytransfer.consumerid = consumerdata.consumerid 

left join interchangetransactions 
on interchangetransactions.consumerid = consumerdata.consumerid 

where consumerdata.signupdate between date(20120101) and curdate() 
group by consumerdata.consumerid order by signupdate asc; 
+0

對於在子查詢中查詢的同一表,您還有'LEFT JOIN'似乎很奇怪。你不應該兩個都做。 – Barmar

+1

哪些表做其他'SELECT'列是從哪裏來的? – Barmar

+0

頂部的select語句都來自consumerdata表。如果你指的是城市,州,年(dob)。 –

回答

1

既然你不選擇從任何交易表的東西,簡單的改善將是擺脫所有LEFT JOIN條款。他們沒有被用於任何事情,因爲你從相關的子查詢中獲得總數。這導致數據庫在所有表之間創建一個巨大的交叉產品,然後在底部執行GROUP BY時將其丟棄。

另一種方法是使用子查詢來計算每個事務表的分組總數,而不是相關子查詢。

select 
    c.consumerid, signupdate, state, year(DOB), topaffiliate, activestatus, lastuseddate, 
    IFNULL(Total_ACH, 0) AS Total_ACH, IFNULL(Bill_Pay, 0) AS Bill_Pay, IFNULL(Revenue, 0) AS Revenue, 
    IFNULL(Cash__TXNs, 0) AS Cash__TXNs, ... 
FROM consumerdata AS c 
LEFT JOIN (
    SELECT consumerid, SUM(transactionamount) AS Total_ACH 
    FROM achload 
    GROUP BY consumerid) AS a ON a.consumerid = c.consumerid 
LEFT JOIN (
    SELECT consumerid, SUM(transactionamount) AS Bill_Pay 
    FROM billpay 
    GROUP BY consumerid) AS b ON b.consumerid = c.consumerid 
LEFT JOIN (
    SELECT consumerid, SUM(transactionamount) AS Revenue 
    FROM recharge 
    GROUP BY consumerid) AS r ON r.consumerid = c.consumerid 
LEFT JOIN (
    SELECT consumerid, COUNT(*) AS Cash__TXNs 
    FROM Cash 
    GROUP BY consumerid) AS cash ON cash.consumerid = c.consumerid 
... 
WHERE c.signupdate between DATE(20120101) and CURDATE() 
ORDER BY signupdate ASC 

我不知道哪條路實際上是更快 - 它很可能將取決於有多少數據是在對消費者,其註冊日期指定範圍之外的事務表。試試看看哪個更好。

+0

非常感謝你的幫助Barmar。查看你的答案後,我現在對如何利用左連接有了更好的理解。 –