【问题标题】:How to set a col val based on 2 other cols in a table in mysql?如何根据mysql中表中的其他2列设置列值?
【发布时间】:2017-12-22 09:55:40
【问题描述】:

在 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

如何做到更有效率?

【问题讨论】:

    标签: mysql inner-join


    【解决方案1】:

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

    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;
    

    【讨论】:

    • 您的回答也很好,效果很好。非常感谢。你心目中哪一个更有效率?
    • 这是一个更好的答案,因为它的复杂性较低。恕我直言
    • 我已经将之前的答案标记为正确!我现在该怎么办!? :-|
    • 你可以随时标记它,如果你愿意,可以标记另一个
    • 这是更好的答案,除非您的数据中有一些可能的重复,我认为情况并非如此 +1。但是请参阅我的答案以了解警告。
    【解决方案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 的权重,这个答案可以很容易地做到这一点。

    【讨论】:

    • 我认为应该有一个简单的解决方案然后这个。让我试着找到那个
    • @Tim :-D 我正在等待 SO 让我这样做。还剩 1 分钟!
    • @Tim,如果您不介意,我会将Md 的答案标记为正确,因为它不那么复杂。好吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2021-12-19
    • 2021-01-03
    • 1970-01-01
    相关资源
    最近更新 更多