如何基于mysql中的表中的2个其他列设置列表?

时间:2017-12-22 09:55:41

标签: mysql inner-join

在mySql中,我尝试根据同一个表中其他2列的值设置列的值(total)。

http://sqlfiddle.com/#!9/e9c27a/1

CREATE TABLE IF NOT EXISTS `order_total` (
    `order_total_id` int(10) NOT NULL AUTO_INCREMENT,
    `order_id` int(11) NOT NULL,
    `code` varchar(32) NOT NULL,
    `title` varchar(255) NOT NULL,
    `value` decimal(15,4) NOT NULL DEFAULT '0.0000',
    `sort_order` int(3) NOT NULL,
    PRIMARY KEY (`order_total_id`),
    KEY `order_id` (`order_id`)
) ENGINE=MyISAM AUTO_INCREMENT=244 DEFAULT CHARSET=utf8;

INSERT INTO `order_total` (`order_total_id`, `order_id`, `code`, `title`, `value`, `sort_order`) VALUES
(241, 80, 'sub_total', 'Sub-Total', '400.0000', 1),
(242, 80, 'shipping', 'Free Shipping', '10.0000', 3),
(243, 80, 'total', 'Total', '0', 9);

我尝试过在本地mySql中运行的代码,但我想也许有更好的方法可以做到这一点。

UPDATE order_total ot 
INNER JOIN (
    SELECT order_id, value
    FROM order_total
        WHERE code = 'sub_total'
    GROUP BY order_id
) o ON ot.order_id = o.order_id
INNER JOIN (
    SELECT order_id, value
    FROM order_total
        WHERE code = 'shipping'
    GROUP BY order_id
) o2 ON ot.order_id = o2.order_id
SET ot.value = o.value + o2.value 
WHERE ot.code = 'total' AND ot.order_id = 80

如何提高效率?

2 个答案:

答案 0 :(得分:2)

您当前的查询在技术上无效,因为子查询正在选择未出现在GROUP BY子句中的非聚合列。但是我们可以通过使用条件聚合来查找每个订单的小计和运费值来解决这个问题并使查询更简洁:

UPDATE order_total ot 
INNER JOIN
(
    SELECT
        order_id,
        MAX(CASE WHEN code = 'sub_total' THEN value END) AS sub_value,
        MAX(CASE WHEN code = 'shipping'  THEN value END) AS shipping_value,
    FROM order_total
    GROUP BY order_id
) o
    ON ot.order_id = o.order_id
SET ot.value = o.sub_value + o.shipping_value
WHERE
    ot.code = 'total' AND
    ot.order_id = 80;

对于这个特殊问题,接受的答案是要走的路。但是如果你想要的不是总和,那么它就行不通了。我的回答是让你做这样的事情:

SET ot.value = o.sub_value + 2*o.shipping_value

也就是说,如果我们想给出运输价值2的重量,这个答案可以很容易地完成。

答案 1 :(得分:2)

您可以使用一个查询计算总数,如下所示:

update order_total ot 
INNER JOIN (
   SELECT order_id, sum(value) value
   FROM order_total
   WHERE code = 'sub_total' or code= 'shipping'
   GROUP BY order_id
) o ON ot.order_id = o.order_id
SET ot.value = o.value
WHERE ot.code = 'total' AND ot.order_id = 80;