mysql派生表聯(lián)表查詢的方法是什么
本文講解"mysql派生表聯(lián)表查詢的方法是什么",希望能夠解決相關(guān)問題。
前情提要:
公司運(yùn)營的一個(gè)商城系統(tǒng),忽然發(fā)現(xiàn)訂單提現(xiàn)功能有問題,有大量的商戶體現(xiàn)金額和訂單金額不一致。于是產(chǎn)生了需求,需要把提現(xiàn)表和供應(yīng)商表作為一個(gè)結(jié)果集,連接上訂單表中的訂單金額,通過計(jì)算訂單表的金額和體現(xiàn)表商戶提現(xiàn)的金額進(jìn)行比對,查看商戶是多提現(xiàn)了還是少提現(xiàn)了。
下面記錄我的查詢過程。
查詢過程:
剛開始,第一步我以提現(xiàn)表為主表,查詢出來相關(guān)結(jié)果。mysql語句如下
select??count(ysw.supply_id)?as?'提現(xiàn)次數(shù)',ysw.user_id?as?'供應(yīng)商對應(yīng)的用戶id',?ysw.supply_id??as?'供應(yīng)商id'?,sum(ysw.money)??as?'供應(yīng)商提現(xiàn)總金額', case?ysw.pay_type?when?10?then?'微信'?when?20?then?'支付寶'?else?'銀行卡'?end?as?'支付方式'?, ys.supply_name?as?'供應(yīng)商名稱',ys.money?as?'供應(yīng)商余額',ys.freez_money?as?'供應(yīng)商凍結(jié)金額(已提現(xiàn)金額)' from?yoshop_supply_withdraw?as?ysw?left?join?yoshop_supply?as?ys?on?ysw.supply_id?=?ys.supply_id where?ysw.create_time?<?1647446400?and?ysw.apply_status?in?(10,20,40)?group?by?ysw.supply_id order?by?sum(ysw.money)?desc?;
查詢結(jié)果如圖是正常的:
接下來,我在左鏈接上訂單表的數(shù)據(jù),又添加一個(gè)了left join,金額相關(guān)數(shù)據(jù)發(fā)生了變化嚴(yán)重不一致,而且查詢時(shí)間明顯延長,mysql語句如下
select??count(ysw.supply_id)?as?'提現(xiàn)次數(shù)',ysw.user_id?as?'供應(yīng)商對應(yīng)的用戶id',?ysw.supply_id??as?'供應(yīng)商id'?,sum(ysw.money)??as?'供應(yīng)商提現(xiàn)總金額', case?ysw.pay_type?when?10?then?'微信'?when?20?then?'支付寶'?else?'銀行卡'?end?as?'支付方式'?, ys.supply_name?as?'供應(yīng)商名稱',ys.money?as?'供應(yīng)商余額',ys.freez_money?as?'供應(yīng)商凍結(jié)金額(已提現(xiàn)金額)',sum(yo.pay_price) from?yoshop_supply_withdraw?as?ysw?left?join?yoshop_supply?as?ys?on?ysw.supply_id?=?ys.supply_id left?join?yoshop_order?as?yo?on?yo.supply_ids?=ysw.supply_id? where?ysw.create_time?<?1647446400?and?ysw.apply_status?in?(10,20,40)?group?by?ysw.supply_id order?by?sum(ysw.money)?desc?;
查詢結(jié)果對比圖如下:
經(jīng)過實(shí)踐,我想直接通過左連接查詢到提現(xiàn)表金額和訂單表金額是行不通的。通過網(wǎng)上查資料,以及在技術(shù)群里請教,
優(yōu)化了思路: 把提現(xiàn)的統(tǒng)計(jì)好,把訂單的統(tǒng)計(jì)好, 最后兩個(gè)結(jié)果集再根據(jù)供應(yīng)商id做個(gè)鏈接
接下來就是,三步走了, 第一步:把提現(xiàn)的統(tǒng)計(jì)好,上面第一次嘗試的第一步就是了, 第二步:把訂單表的數(shù)據(jù)統(tǒng)計(jì)好。由于使用系統(tǒng)的原因,我直接使用的訂單商品表計(jì)算的訂單總金額,這一步也是分三步走的,我直接上代碼:
1.查詢yoshop_order所有進(jìn)行中,已完成的?訂單id(order_id); select?order_id?from?yoshop_order?where?order_status?in?(10,30); 2.查詢沒有退款的訂單id select?order_id?from?yoshop_order?where?order_status?in?(10,30)?and?order_id?not?in?(?select?order_id?from?yoshop_order_refund); 3.查詢訂單商品表中?所有的訂單金額 select??supply_id??as?'供應(yīng)商id'?,?sum(total_pay_price)??as?'供應(yīng)商訂單總金額'?from?yoshop_order_goods?where??create_time?<?1647446400?and?order_pay_status?=?0??and??order_id?in(select?order_id?from?yoshop_order?where?order_status?in?(10,30)?and?order_id?not?in?(?select?order_id?from?yoshop_order_refund) ?)??group?by?supply_id? order?by?sum(total_pay_price)?desc?;
接下來就是進(jìn)行把第一步和第二步的查詢結(jié)果當(dāng)作派生表,進(jìn)行左連接查詢。我在這一步耗費(fèi)的時(shí)間和精力最多。如果你能認(rèn)真看完,相信一定會(huì)有收貨。我在這里把我錯(cuò)誤的過程也進(jìn)行了記錄 第一次錯(cuò)誤拼接:
select?*?from??( select??count(ysw.supply_id)?as?'提現(xiàn)次數(shù)',ysw.user_id?as?'供應(yīng)商對應(yīng)的用戶id',?ysw.supply_id??as?'supply_id'?,sum(ysw.money)??as?'供應(yīng)商提現(xiàn)總金額', case?ysw.pay_type?when?10?then?'微信'?when?20?then?'支付寶'?else?'銀行卡'?end?as?'支付方式'?, ys.supply_name?as?'供應(yīng)商名稱',ys.money?as?'供應(yīng)商余額',ys.freez_money?as?'供應(yīng)商凍結(jié)金額(已提現(xiàn)金額)' from?yoshop_supply_withdraw?as?ysw?left?join?yoshop_supply?as?ys?on?ysw.supply_id?=?ys.supply_id where?ysw.create_time?<?1647446400?and?ysw.apply_status?in?(10,20,40)?group?by?ysw.supply_id order?by?sum(ysw.money)?desc?)?as?t1? union?all????//?left?join?,這里是注釋記得刪除 select?*?from???--??這里是錯(cuò)誤的不應(yīng)該在查詢 (select??supply_id??as?'supply_id'?,?sum(total_pay_price)??as?total_pay_price?from?yoshop_order_goods?where??create_time?<?1647446400?and?order_pay_status?=?0??and??order_id?in( select?order_id?from?yoshop_order?where?order_status?in?(10,30)?and?order_id?not?in?( select?order_id?from?yoshop_order_refund) ?)??group?by?supply_id? order?by?sum(total_pay_price)?desc?)?as?t2 on?t1.suppply_id?=?t2.suppply_id
通過這一次試錯(cuò),明顯看出我把left join 和 union all 的含義記錯(cuò)了,并且在拼接的時(shí)候重復(fù)使用了select * from 。雖然是試錯(cuò)了,但也是有收貨的,接下來進(jìn)行了第二次錯(cuò)誤的拼接:
select?t1.提現(xiàn)次數(shù)?,t1.供應(yīng)商對應(yīng)的用戶id?,t1.supply_id,?t1.支付方式?,t1.供應(yīng)商名稱,t1.供應(yīng)商余額,?t1.供應(yīng)商凍結(jié)金額(已提現(xiàn)金額),?t2.total_pay_price?from??( select??count(ysw.supply_id)?as?'提現(xiàn)次數(shù)',ysw.user_id?as?'供應(yīng)商對應(yīng)的用戶id',?ysw.supply_id??as?supply_id?,sum(ysw.money)??as?'供應(yīng)商提現(xiàn)總金額', case?ysw.pay_type?when?10?then?'微信'?when?20?then?'支付寶'?else?'銀行卡'?end?as?'支付方式'?, ys.supply_name?as?'供應(yīng)商名稱',ys.money?as?'供應(yīng)商余額',ys.freez_money?as?'供應(yīng)商凍結(jié)金額(已提現(xiàn)金額)' from?yoshop_supply_withdraw?as?ysw?left?join?yoshop_supply?as?ys?on?ysw.supply_id?=?ys.supply_id where?ysw.create_time?<?1647446400?and?ysw.apply_status?in?(10,20,40)?group?by?ysw.supply_id order?by?sum(ysw.money)?desc?)?as?t1? ???????? ?left?join (select??supply_id??as?supply_id?,?sum(total_pay_price)??as?total_pay_price?from? yoshop_order_goods?where??create_time?<?1647446400?and?order_pay_status?=?0?? and??order_id?in( select?order_id?from?yoshop_order?where?order_status?in?(10,30)? and?order_id?not?in?( select?order_id?from?yoshop_order_refund) ?)?? group?by?supply_id? order?by?sum(total_pay_price)?desc?)?as?t2 on?t1.suppply_id?=?t2.suppply_id
通過這兩次錯(cuò)誤的嘗試,以及根據(jù)嘗試過程中mysql給出的錯(cuò)誤提示,知道自己是在左連接上使用錯(cuò)誤了,應(yīng)該在開始查詢出來所有的字段,left join 后不能在使用select * 最后,回想了一遍自己所學(xué)的left join的語法,寫出了最后的正確的查詢結(jié)果
select?t1.supply_id?'供應(yīng)商id',t1.supply_name?'供應(yīng)商名稱',t1.user_id?'供應(yīng)商綁定的用戶id',t1.withdrawtime?'供應(yīng)商提現(xiàn)次數(shù)'?,t1.supplyallmoney?'供應(yīng)商提現(xiàn)金額',t1.payway?'供應(yīng)商提現(xiàn)方式',t1.supply_money?'供應(yīng)商賬戶余額',t1.supply_free_money?'供應(yīng)商凍結(jié)余額(已提現(xiàn)金額)', t2.total_pay_price?'供應(yīng)商訂單總金額',t2.order_id?'供應(yīng)商訂單數(shù)量' from??( select??count(ysw.supply_id)?as?withdrawtime,??ysw.user_id?as?user_id,???ysw.supply_id??as?supply_id?,??sum(ysw.money)??as?supplyallmoney,???ysw.alipay_name?as?alipay_name?,ysw.alipay_account?as?alipay_account,??ysw.audit_time?as?audit_time?,??ysw.bank_account?as?bank_account,???ysw.bank_card?as?bank_card,???ysw.bank_name?as?bank_name, case?ysw.pay_type?when?10?then?'微信'?when?20?then?'支付寶'?else?'銀行卡'?end?as?payway?, ys.supply_name?as?supply_name,??ys.money?as?supply_money,??ys.freez_money?as?supply_free_money from?yoshop_supply_withdraw?as?ysw?left?join?yoshop_supply?as?ys?on?ysw.supply_id?=?ys.supply_id where?ysw.create_time?<?1647446400?and?ysw.apply_status?in?(10,20,40)?group?by?ysw.supply_id order?by?sum(ysw.money)?desc?)?as?t1? ?left?join ????(select??supply_id??as?'supply_id'?,?count(order_id)?as?order_id,???sum(total_pay_price)????as?total_pay_price? ????from? yoshop_order_goods?where??create_time?<?1647446400?and?order_pay_status?=?0?? ????and??order_id?in( ????????select?order_id?from?yoshop_order?where?order_status?in?(10,30)? ????and?order_id?not?in?( ????????select?order_id?from?yoshop_order_refund) ?)? ????group?by?supply_id? ????order?by?sum(total_pay_price)?desc?)?as?t2 on?t1.supply_id?=?t2.supply_id
正確的結(jié)果截圖:
關(guān)于 "mysql派生表聯(lián)表查詢的方法是什么" 就介紹到此。希望多多支持碩編程。