使用作业日期将产品表连接到价格更改表

时间:2013-07-19 19:19:07

标签: mysql

我有一个看起来像这样的工作表:

**jobs**

 job_id | customer_id | date
------------------------------------
|    1  |           1 | 2012-01-03 |
|    2  |           2 | 2013-02-04 |
|    3  |           1 | 2013-03-05 |
|    4  |           3 | 2013-05-04 |

然后我有一个产品表,看起来像这样:

**products**

 product_id | description | price
-----------------------------------
|         1 |      prod_1 | 25.50 | 
|         2 |      prod_2 | 34.95 |

最后,当价格发生变化时,我有一个像这样的product_price_changes表:

**product_price_changes**

 price_change_id | product_id | price_change_date | old_price
---------------------------------------------------------------
|              1 |          1 |        2013-01-01 |     20.00 |
|              2 |          1 |        2013-02-05 |     23.00 |

使用UNIQUE INDEX(product_id,price_change_date)

我想创建一个VIEW来抓住产品定价,反映从工作完成之日起的价格。

,根据上面的数据,应该创建一个这样的表:

**view_job_pricing**

 job_id | product_id | price
------------------------------
|     1 |          1 | 20.00 |
|     1 |          2 | 34.95 |
|     2 |          1 | 23.00 |
|     2 |          2 | 34.95 |
|     3 |          1 | 25.50 |
|     3 |          2 | 34.95 |
|     4 |          1 | 25.50 |
|     4 |          2 | 34.95 |

所以它应该选择具有最高日期的产品价格变化,如果它仍然存在,那么它仍然小于作业日期,否则它应该抓住当前的产品价格。

我有这个有效:

CREATE VIEW view_job_pricing 
AS
SELECT j.job_id, p.product_id, MAX(price_change_date), 
       IFNULL(ppc.old_price,p.price) AS price
FROM products p
JOIN jobs j
LEFT JOIN product_price_changes ppc 
          ON p.product_id = ppc.product_id AND date < price_change_date
GROUP BY job_id, product_id;

但它在真实数据库上的速度相当慢(更多的工作和产品)。只是想知道是否有更好的方法。谢谢!

2 个答案:

答案 0 :(得分:1)

尝试将此作为相关子查询。您可以在视图的select子句中使用子查询,并且相关子查询应该使用产品上的索引。

CREATE VIEW view_job_pricing 
AS
SELECT j.job_id, p.product_id, MAX(price_change_date), 
       coalesce((select ppc.price
                 from product_price_changes ppc
                 where p.product_id = ppc.product_id AND j.date < ppc.price_change_date
                 order by ppc.price_change_date desc
                 limit 1
                ),
                p.price) AS price
FROM products p cross join
     jobs j

您可以通过更改product_price_changes表的结构来简化处理并提高性能。而不是只有一个effective_date,也有一个end_date。使用effdateenddate列,查询会更快更简单。

答案 1 :(得分:1)

除了为所有相关列编制索引,并使用EXPLAIN EXTENDED(您可以在此处发布以供审核)检查索引结果外,您还可以尝试通过将其定义为CREATE ALGORITHM = MERGE VIEW来加快视图速度。关于何时可以做到这一点有很多限制,所以YMMV

[http://dev.mysql.com/doc/refman/5.0/en/create-view.html] [1]