基于第三个“关键”表从两个表中返回值,然后将值与求和乘积相乘

时间:2013-07-27 23:13:04

标签: mysql join match case correlated-subquery

我有三张桌子:

Value v

+-------------------------------+
| Owner | Location |    Value   |
+-------------------------------+
|Bob    |    A1    |    0.25    |
|Bob    |    B4    |    0.10    |
|Dale   |    Z3    |    0.50    |
|Dale   |    A1    |    0.25    |
|Rick   |    B4    |    0.10    |
|Rick   |    Z3    |    0.50    |
+-------------------------------+

PurchasePercentage p

+-------------------------------+
| Buyer | Location | Percentage |
+-------------------------------+
|Bill   |    A1    |    0.10    |
|Bill   |    B4    |    0.20    |
|Kyle   |    Z3    |    0.30    |
|Kyle   |    A1    |    0.50    |
|Jan    |    B4    |    0.15    |
|Jan    |    Z3    |    0.25    |
+-------------------------------+

Buyout b

+------------------+
| Owner |   Buyer  |
+------------------+
|Bob    |   Bill   |
|Bob    |   Kyle   |
|Dale   |   Jan    |
|Dale   |   Bill   |
|Rick   |   Kyle   |
|Rick   |   Jan    |
+------------------+

我正在寻找的是第四张桌子:

PossibleBuyouts

+--------------------------------+
| Owner |   Buyer  |  BuyoutCost |
+--------------------------------+

基于Buyout表格中列出的交易 其中BuyoutCostv.Value * p.Percentage的总和 对于每个不同的Location
BuyerOwner有共同之处。

因此,这些示例将返回<{p}}的PossibleBuyouts

+--------------------------------+
| Owner |   Buyer  |  BuyoutCost |
+--------------------------------+
|Bob    |   Bill   |    0.045    |
|Bob    |   Kyle   |    0.125    |
|Dale   |   Jan    |    0.125    |
|Dale   |   Bill   |    0.025    |
|Rick   |   Kyle   |    0.150    |
|Rick   |   Jan    |    0.140    |
+--------------------------------+

将第一行作为示例,数学运算如下:

-Bob和Bill共有地点A1和B4 -Bob的A1所有权价值为0.25,比尔要求0.10% - A1的成本为(0.25 * 0.10)= 0.025
-Bob对B4的所有权价值为0.10,比尔要求0.20% - B4的成本为(0.10 * 0.20)= 0.020
-Sum(0.025 + 0.020)=买入成本0.045。

如果你可以帮助我,我正在寻找最有效的方法来做到这一点 - 无论是多个查询,一个带有一堆子查询的查询,还是应该花费最少的时间

有大约1500个不同的所有者,~1000个不同的买家和~500个不同的位置,因此潜在组合的数量导致looooooong查询时间。你认为最快的方法是什么?所有东西都被编入索引,数据减少到我可以得到的最小尺寸。

1 个答案:

答案 0 :(得分:0)

我建议您创建一个使用光标来完成目标的过程。迭代三个表中的一个,它应该是一个非常简单的过程。

MySQL游标:http://dev.mysql.com/doc/refman/5.0/en/cursors.html

编辑:以下存储的MySQL脚本创建并调用存储过程,该存储过程正确地再现您正在查找的结果:

DELIMITER $$

DROP PROCEDURE IF EXISTS `computeBuyouts` $$
CREATE PROCEDURE `computeBuyouts` ()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE o, b VARCHAR(32);
DECLARE bc FLOAT;
DECLARE cur CURSOR FOR SELECT Owner,Buyer FROM Buyout;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN cur;

read_loop: LOOP
  FETCH cur INTO o, b;
  IF done THEN
    LEAVE read_loop;
  END IF;

  SET bc = 0;
  -- compute the sum of products of each value/percentage pair for all locations 
  SELECT SUM(v.Value * pp.Percentage) INTO bc FROM Value v LEFT JOIN (PurchasePercentage pp) ON (v.Location = pp.Location) where v.Owner = o and pp.Buyer = b group by v.Owner;

  INSERT INTO PossibleBuyouts VALUES (o, b, bc);

END LOOP;

CLOSE cur;

END $$

DELIMITER ;

CALL computeBuyouts();

希望有所帮助。在您提到的表格大小中,这应该非常快速地完成。