如何从MySQL中另一个表的结果有效地更新表中的所有记录

时间:2016-08-24 15:50:31

标签: mysql

我有两个MySQL表定义如下:

CREATE TABLE product_daily_summary (
    date DATE,
    product_id INT UNSIGNED,
    orders  INT NOT NULL,
    sales    INT NOT NULL,
    PRIMARY KEY (date, product_id)
);

CREATE TABLE product_summary (
    product_id  INT UNSIGNED,
    seven_day_orders  INT NOT NULL,
    seven_day_sales   INT NOT NULL,
    thirty_day_orders  INT NOT NULL,
    thirty_day_sales  INT NOT NULL,
    start_date date,
    PRIMARY KEY (product_id)
);

每当在product_daily_summary中插入或更新记录时,我也会自动插入或更新到product_summary表。

DELIMITER $$
CREATE TRIGGER after_product_daily_summary_insert 
               AFTER INSERT ON product_daily_summary
FOR EACH ROW
BEGIN
    INSERT INTO product_summary (product_id, seven_day_orders, seven_day_sales, 
                                thirty_day_orders, thirty_day_sales, start_date)
    VALUES (NEW.product_id, NEW.orders, NEW.sales, NEW.orders, NEW.sales, NEW.date)
    ON DUPLICATE KEY UPDATE 
                    start_date         =   LEAST(start_date, NEW.date),
                    seven_day_orders   =   seven_day_orders   +  NEW.orders,
                    seven_day_sales    =   seven_day_sales    +  NEW.sales,
                    thirty_day_orders  =   thirty_day_orders  +  NEW.orders,
                    thirty_day_sales   =   thirty_day_sales   +  NEW.sales;
END $$
DELIMITER ;


DELIMITER $$
CREATE TRIGGER after_product_daily_summary_update 
               AFTER UPDATE ON product_daily_summary
FOR EACH ROW
BEGIN
    INSERT INTO product_summary (product_id, seven_day_sales, seven_day_orders, 
                                thirty_day_sales, thirty_day_orders, start_date)

    VALUES (NEW.product_id, NEW.sales, NEW.orders, NEW.sales, NEW.orders, NEW.date)
    ON DUPLICATE KEY UPDATE 
                    start_date         =  LEAST(start_date, NEW.date),
                    seven_day_sales    =  seven_day_sales   + NEW.sales  - OLD.sales,
                    seven_day_orders   =  seven_day_orders  + NEW.orders - OLD.orders,
                    thirty_day_sales   =  thirty_day_sales  + NEW.sales  - OLD.sales,
                    thirty_day_orders  =  thirty_day_orders + NEW.orders - OLD.orders;
END $$
DELIMITER ;

product_daily_summaryproduct_summary的部分记录如下所示

select * from product_daily_summary;

mysql> select * from product_daily_summary;

|   date     | product_id | order  | sales |
--------------------------------------------
| 2016-08-03 |      14169 |     46 |  1380 |
| 2016-08-03 |      18090 |     28 |   840 |
| 2016-08-03 |      37979 |     14 |   420 |
| 2016-08-03 |      75847 |     27 |   810 |
| 2016-08-03 |      99873 |     49 |  1470 |
| 2016-08-04 |      14169 |     60 |  1800 |
| 2016-08-04 |      18090 |     29 |   870 |
| 2016-08-04 |      37979 |      5 |   150 |
| 2016-08-04 |      75847 |     47 |  1410 |
| 2016-08-04 |      99873 |     14 |   420 |
| 2016-08-05 |      14169 |     29 |   870 |
| 2016-08-05 |      18090 |     47 |  1410 |
| 2016-08-05 |      37979 |     14 |   420 |
| 2016-08-05 |      75847 |     22 |   660 |
| 2016-08-05 |      99873 |      6 |   180 |
| 2016-08-06 |      14169 |     18 |   540 |
| 2016-08-06 |      18090 |     12 |   360 |
| 2016-08-06 |      37979 |     27 |   810 |
| 2016-08-06 |      75847 |     43 |  1290 |
| 2016-08-06 |      99873 |     15 |   450 |
| 2016-08-07 |      14169 |     43 |  1290 |
| 2016-08-07 |      18090 |     18 |   540 |
| 2016-08-07 |      37979 |     22 |   660 |
| 2016-08-07 |      75847 |    311 |  9330 |
| 2016-08-07 |      99873 |     54 |  1620 |
| 2016-08-08 |      14169 |      4 |   120 |
| 2016-08-08 |      18090 |     43 |  1290 |
| 2016-08-08 |      37979 |     72 |  2160 |
| 2016-08-08 |      75847 |     94 |  2820 |
| 2016-08-08 |      99873 |      5 |   150 |
| 2016-08-09 |      14169 |    105 |  3150 |
| 2016-08-09 |      18090 |    101 |  3030 |
| 2016-08-09 |      37979 |     22 |   660 |
| 2016-08-09 |      75847 |    123 |  3690 |
| 2016-08-09 |      99873 |     30 |   900 |
| 2016-08-10 |      14169 |     43 |  1290 |
| 2016-08-10 |      18090 |     22 |   660 |
| 2016-08-10 |      37979 |    153 |  4590 |
| 2016-08-10 |      75847 |     52 |  1560 |
| 2016-08-10 |      99873 |     46 |  1380 |
| 2016-08-11 |      14169 |     66 |  1980 |
| 2016-08-11 |      18090 |     18 |   540 |
| 2016-08-11 |      37979 |     26 |   780 |
| 2016-08-11 |      75847 |     11 |   330 |
| 2016-08-11 |      99873 |     54 |  1620 |
| 2016-08-12 |      14169 |     38 |  1140 |
| 2016-08-12 |      18090 |      5 |   150 |
| 2016-08-12 |      37979 |     20 |   600 |
| 2016-08-12 |      75847 |     28 |   840 |
| 2016-08-12 |      99873 |     20 |   600 |
| 2016-08-13 |      14169 |     84 |  2520 |
| 2016-08-13 |      18090 |     41 |  1230 |
| 2016-08-13 |      37979 |     90 |  2700 |
| 2016-08-13 |      75847 |     24 |   720 |
| 2016-08-13 |      99873 |     40 |  1200 |
| 2016-08-14 |      14169 |     50 |  1500 |
| 2016-08-14 |      18090 |     93 |  2790 |
| 2016-08-14 |      37979 |     16 |   480 |
| 2016-08-14 |      75847 |     33 |   990 |
| 2016-08-14 |      99873 |     61 |  1830 |
| 2016-08-15 |      14169 |     12 |   360 |
| 2016-08-15 |      18090 |    105 |  3150 |
| 2016-08-15 |      37979 |     18 |   540 |
| 2016-08-15 |      75847 |     28 |   840 |
| 2016-08-15 |      99873 |     82 |  2460 |
| 2016-08-16 |      14169 |     31 |   930 |
| 2016-08-16 |      18090 |      1 |    30 |
| 2016-08-16 |      37979 |    124 |  3720 |
| 2016-08-16 |      75847 |     61 |  1830 |
| 2016-08-16 |      99873 |     22 |   660 |
| 2016-08-17 |      14169 |     21 |   630 |
| 2016-08-17 |      18090 |     59 |  1770 |
| 2016-08-17 |      37979 |     11 |   330 |
| 2016-08-17 |      75847 |     90 |  2700 |
| 2016-08-17 |      99873 |     28 |   840 |
| 2016-08-18 |      14169 |     28 |   840 |
| 2016-08-18 |      18090 |     12 |   360 |
| 2016-08-18 |      37979 |     15 |   450 |
| 2016-08-18 |      75847 |     49 |  1470 |
| 2016-08-18 |      99873 |     20 |   600 |
| 2016-08-19 |      14169 |     66 |  1980 |
| 2016-08-19 |      18090 |      6 |   180 |
| 2016-08-19 |      37979 |     19 |   570 |
| 2016-08-19 |      75847 |     57 |  1710 |
| 2016-08-19 |      99873 |      6 |   180 |
| 2016-08-20 |      14169 |    130 |  3900 |
| 2016-08-20 |      18090 |     26 |   780 |
| 2016-08-20 |      37979 |    136 |  4080 |
| 2016-08-20 |      75847 |     29 |   870 |
| 2016-08-20 |      99873 |      1 |    30 |
| 2016-08-21 |      14169 |     89 |  2670 |
| 2016-08-21 |      18090 |     17 |   510 |
| 2016-08-21 |      37979 |     82 |  2460 |
| 2016-08-21 |      75847 |      7 |   210 |
| 2016-08-21 |      99873 |     55 |  1650 |
| 2016-08-22 |      14169 |     78 |  2340 |
| 2016-08-22 |      18090 |     10 |   300 |
| 2016-08-22 |      37979 |      3 |    90 |
| 2016-08-22 |      75847 |     27 |   810 |
| 2016-08-22 |      99873 |     29 |   870 |
| 2016-08-23 |      14169 |     38 |  1140 |
| 2016-08-23 |      18090 |      2 |    60 |
| 2016-08-23 |      37979 |     39 |  1170 |
| 2016-08-23 |      75847 |     98 |  2940 |
| 2016-08-23 |      99873 |    137 |  4110 |
| 2016-08-24 |      14169 |     69 |  2070 |
| 2016-08-24 |      18090 |     40 |  1200 |
| 2016-08-24 |      37979 |     45 |  1350 |
| 2016-08-24 |      75847 |     50 |  1500 |
| 2016-08-24 |      99873 |     35 |  1050 |
| 2016-08-25 |      14169 |     81 |  2430 |
| 2016-08-25 |      18090 |     98 |  2940 |
| 2016-08-25 |      37979 |     49 |  1470 |
| 2016-08-25 |      75847 |     19 |   570 |
| 2016-08-25 |      99873 |     34 |  1020 |
| 2016-08-26 |      14169 |     10 |   300 |
| 2016-08-26 |      18090 |     28 |   840 |
| 2016-08-26 |      37979 |     29 |   870 |
| 2016-08-26 |      75847 |     42 |  1260 |
| 2016-08-26 |      99873 |     43 |  1290 |
| 2016-08-27 |      14169 |     99 |  2970 |
| 2016-08-27 |      18090 |     46 |  1380 |
| 2016-08-27 |      37979 |     19 |   570 |
| 2016-08-27 |      75847 |    136 |  4080 |
| 2016-08-27 |      99873 |     19 |   570 |
| 2016-08-28 |      14169 |     55 |  1650 |
| 2016-08-28 |      18090 |     53 |  1590 |
| 2016-08-28 |      37979 |     84 |  2520 |
| 2016-08-28 |      75847 |     21 |   630 |
| 2016-08-28 |      99873 |     16 |   480 |
| 2016-08-29 |      14169 |     37 |  1110 |
| 2016-08-29 |      18090 |     18 |   540 |
| 2016-08-29 |      37979 |     29 |   870 |
| 2016-08-29 |      75847 |      0 |     0 |
| 2016-08-29 |      99873 |     84 |  2520 |
| 2016-08-30 |      14169 |      2 |    60 |
| 2016-08-30 |      18090 |     25 |   750 |
| 2016-08-30 |      37979 |    119 |  3570 |
| 2016-08-30 |      75847 |     40 |  1200 |
| 2016-08-30 |      99873 |     18 |   540 |
| 2016-08-31 |      14169 |     59 |  1770 |
| 2016-08-31 |      18090 |     90 |  2700 |
| 2016-08-31 |      37979 |     56 |  1680 |
| 2016-08-31 |      75847 |     12 |   360 |
| 2016-08-31 |      99873 |    169 |  5070 |
| 2016-09-01 |      14169 |     27 |   810 |
| 2016-09-01 |      18090 |      4 |   120 |
| 2016-09-01 |      37979 |     42 |  1260 |
| 2016-09-01 |      75847 |     47 |  1410 |
| 2016-09-01 |      99873 |     31 |   930 |
+------------+------------+--------+-------+

150 rows in set (0.02 sec)


mysql> select * from product_summary;

+------------+------------------+-----------------+-------------------+------------------+------------+
| product_id |seven_day_orders  | seven_day_sales | thirty_day_orders | thirty_day_sales | start_date |
+------------+------------------+-----------------+-------------------+------------------+------------+
|      14169 |             1518 |           45540 |              1518 |            45540 | 2016-08-03 |
|      18090 |             1097 |           32910 |              1097 |            32910 | 2016-08-03 |
|      37979 |             1400 |           42000 |              1400 |            42000 | 2016-08-03 |
|      75847 |             1628 |           48840 |              1628 |            48840 | 2016-08-03 |
|      99873 |             1223 |           36690 |              1223 |            36690 | 2016-08-03 |
+------------+------------------+-----------------+-------------------+------------------+------------+

5 rows in set (0.03 sec)

现在我的要求是更新seven_day_orders表格中的seven_day_salesthirty_day_ordersthirty_day_salesproduct_summary列,seven_day_orders和{{ 1}}是过去7天内的seven_day_salessum( orders)sum(sales)thirty_day_sales代表销售的thirty_day_orders以及从当前日期开始的过去30天的订单。


现在我需要有效地更新sum表。我在product_summary表中有数十亿条记录。此外,如果过去7天内没有产品的销售或订单,则product_daily_summary表中的相应条目(seven_day_ordersseven_day_sales)应为零。

0 个答案:

没有答案