Maison  >  Article  >  base de données  >  Exemple d'analyse d'une requête de jointure de table dérivée de MySQL

Exemple d'analyse d'une requête de jointure de table dérivée de MySQL

PHPz
PHPzavant
2023-04-17 18:40:061230parcourir

Résumé préliminaire :

Un système de centre commercial exploité par l'entreprise a soudainement découvert qu'il y avait un problème avec la fonction de retrait de commande. Un grand nombre de commerçants ont signalé que le montant n'était pas cohérent avec le montant de la commande. Une demande est donc apparue. Il était nécessaire d'utiliser la table de retrait et la table des fournisseurs comme ensemble de résultats, de relier le montant de la commande dans la table de commande et de comparer le montant de la table de commande avec le montant retiré par le commerçant dans la table de réflexion. pour vérifier si le commerçant a retiré plus d'argent. Encore moins de retraits.

Mon processus de requête est enregistré ci-dessous.

Processus de requête :

Au début, dans la première étape, j'ai utilisé la table de retrait comme table principale pour interroger les résultats pertinents. L'instruction MySQL est la suivante

SELECT  count(ysw.supply_id) AS '提现次数',ysw.user_id AS '供应商对应的用户ID', ysw.supply_id  AS '供应商ID' ,SUM(ysw.money)  AS '供应商提现总金额',
case ysw.pay_type when 10 then '微信' when 20 then '支付宝' else '银行卡' end as '支付方式' ,
ys.supply_name AS '供应商名称',ys.money AS '供应商余额',ys.freez_money AS '供应商冻结金额(已提现金额)'
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 ;

Les résultats de la requête sont normaux comme indiqué :

Exemple d'analyse d'une requête de jointure de table dérivée de MySQL

Ensuite, j'ai ajouté une jointure gauche aux données de la table de commande sur le lien de gauche. Les données liées au montant ont changé et étaient sérieusement incohérentes, et la requête Le temps est évidemment prolongé, et l'instruction MySQL est la suivante

SELECT  count(ysw.supply_id) AS &#39;提现次数&#39;,ysw.user_id AS &#39;供应商对应的用户ID&#39;, ysw.supply_id  AS &#39;供应商ID&#39; ,SUM(ysw.money)  AS &#39;供应商提现总金额&#39;,
case ysw.pay_type when 10 then &#39;微信&#39; when 20 then &#39;支付宝&#39; else &#39;银行卡&#39; end as &#39;支付方式&#39; ,
ys.supply_name AS &#39;供应商名称&#39;,ys.money AS &#39;供应商余额&#39;,ys.freez_money AS &#39;供应商冻结金额(已提现金额)&#39;,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 ;

Le tableau de comparaison des résultats de la requête est le suivant :

Exemple d'analyse d'une requête de jointure de table dérivée de MySQL

Après la pratique, je souhaite interroger directement le montant de la table de retrait et le montant de la table de commande via la jointure à gauche n'est pas réalisable. En vérifiant les informations en ligne et en demandant conseil au groupe technique,

a optimisé l'idée : faire de bonnes statistiques sur les retraits d'espèces, faire de bonnes statistiques sur les commandes, et faire un lien basé sur l'ID fournisseur pour les deux derniers jeux de résultats

Le la prochaine étape est, trois Allons-y étape par étape. La première étape : Collecter les statistiques de retraits La première étape de la tentative ci-dessus est la première étape : Collecter les données du tableau des commandes. En raison de l'utilisation du système, j'utilise directement le tableau des produits de la commande pour calculer le montant total de la commande. Cette étape est également divisée en trois étapes. Je saisis directement le code :

1.查询yoshop_order所有进行中,已完成的 订单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 &#39;供应商ID&#39; , SUM(total_pay_price)  AS &#39;供应商订单总金额&#39; 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 ;

L'étape suivante consiste à interroger la première et la deuxième. étapes. Le résultat est utilisé comme table dérivée pour la requête de jointure gauche. C’est l’étape où je consacre le plus de temps et d’énergie. Si vous pouvez le lire attentivement, je pense que vous le recevrez. J'ai également enregistré mon mauvais processus ici. Le premier mauvais épissage :

SELECT * FROM  (
	SELECT  count(ysw.supply_id) AS &#39;提现次数&#39;,ysw.user_id AS &#39;供应商对应的用户ID&#39;, ysw.supply_id  AS &#39;supply_id&#39; ,SUM(ysw.money)  AS &#39;供应商提现总金额&#39;,
	case ysw.pay_type when 10 then &#39;微信&#39; when 20 then &#39;支付宝&#39; else &#39;银行卡&#39; end as &#39;支付方式&#39; ,
	ys.supply_name AS &#39;供应商名称&#39;,ys.money AS &#39;供应商余额&#39;,ys.freez_money AS &#39;供应商冻结金额(已提现金额)&#39;
	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   --  这里是错误的不应该在查询
		(SELECT  supply_id  AS &#39;supply_id&#39; , 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

À travers ces essais et erreurs, il était évident que j'avais mal mémorisé la signification de la jointure gauche et de l'union, et que je les avais réutilisés lors de l'épissage. Bien qu'il s'agisse d'essais et d'erreurs, les marchandises ont été reçues, puis un deuxième mauvais épissage a été effectué :

SELECT t1.提现次数 ,t1.供应商对应的用户ID ,t1.supply_id, t1.支付方式 ,t1.供应商名称,t1.供应商余额, t1.供应商冻结金额(已提现金额), t2.total_pay_price FROM  (
SELECT  count(ysw.supply_id) AS &#39;提现次数&#39;,ysw.user_id AS &#39;供应商对应的用户ID&#39;, ysw.supply_id  AS supply_id ,SUM(ysw.money)  AS &#39;供应商提现总金额&#39;,
case ysw.pay_type when 10 then &#39;微信&#39; when 20 then &#39;支付宝&#39; else &#39;银行卡&#39; end as &#39;支付方式&#39; ,
	ys.supply_name AS &#39;供应商名称&#39;,ys.money AS &#39;供应商余额&#39;,ys.freez_money AS &#39;供应商冻结金额(已提现金额)&#39;
	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

Grâce à ces deux mauvaises tentatives, et sur la base des invites d'erreur données par MySQL lors de la tentative, je savais que j'étais moi-même. J'ai fait une erreur en utilisant la jointure gauche. Je devrais interroger tous les champs au début. Je ne peux pas utiliser select * après la jointure gauche. Enfin, j'ai rappelé la syntaxe de jointure gauche que j'ai apprise et j'ai écrit le résultat final de la requête correcte

SELECT t1.supply_id &#39;供应商ID&#39;,t1.supply_name &#39;供应商名称&#39;,t1.user_id &#39;供应商绑定的用户ID&#39;,t1.withdrawtime &#39;供应商提现次数&#39; ,t1.supplyallmoney &#39;供应商提现金额&#39;,t1.payway &#39;供应商提现方式&#39;,t1.supply_money &#39;供应商账户余额&#39;,t1.supply_free_money &#39;供应商冻结余额(已提现金额)&#39;,
t2.total_pay_price &#39;供应商订单总金额&#39;,t2.order_id &#39;供应商订单数量&#39;
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 &#39;微信&#39; when 20 then &#39;支付宝&#39; else &#39;银行卡&#39; 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 &#39;supply_id&#39; , 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

Corriger. capture d'écran du résultat :

Exemple d'analyse d'une requête de jointure de table dérivée de MySQL

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer