【问题标题】:MySQL - sums are getting multipliedMySQL - 总和正在成倍增加
【发布时间】:2021-08-02 03:54:54
【问题描述】:

我正在尝试从table_a 获取数据,左侧的sum() 加入table_b,另一个左侧的sum() 加入table_c

所以,加入ab

SELECT a.id, a.name, sum(b.quantity)
FROM table_a a
LEFT JOIN table_b b on b.id_table_a = a.id
GROUP BY a.id;

输出

id name sum(b.quantity)
1 test 14

并且,加入ac

SELECT a.id, a.name, sum(c.quantity)
FROM table_a a
LEFT JOIN table_c c on c.id_table_a = a.id
GROUP BY a.id;

输出

id name sum(c.quantity)
1 test 8

当我尝试同时加入abc 时出现问题

SELECT a.id, a.name, SUM(b.quantity), SUM(c.quantity)
FROM table_a a
LEFT JOIN table_b b ON b.id_table_a = a.id
LEFT JOIN table_c c ON c.id_table_a = a.id
GROUP BY a.id;

输出

id name sum(b.quantity) sum(c.quantity)
1 test 28 24

sum() 乘以连接表中的行数(14x2 和 8x3)

此时的问题是:我怎样才能得到正确的总和?

这是我所期望的:

id name sum(b.quantity) sum(c.quantity)
1 test 14 8

现在我正在执行以下操作,但我想知道使用上一个查询是否可以实现相同的结果,也许我在 group by 中遗漏了一些东西?

SELECT 
    x.*, SUM(c.quantity)
FROM
    (SELECT 
        a.id, a.name, SUM(b.quantity)
    FROM
        table_a a
    LEFT JOIN table_b b ON b.id_table_a = a.id
    GROUP BY a.id) x
        LEFT JOIN
    table_c c ON c.id_table_a = x.id
GROUP BY x.id;

这是一个指向小提琴的链接,位于 SQL 下方

http://sqlfiddle.com/#!9/b40639

CREATE TABLE `table_a` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(50) NULL,
  PRIMARY KEY (`id`));

CREATE TABLE `table_b` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `id_table_a` INT UNSIGNED NOT NULL,
  `quantity` TINYINT UNSIGNED NULL,
  PRIMARY KEY (`id`),
  INDEX `fk_table_b_id_table_a1_idx` (`id_table_a` ASC),
  CONSTRAINT `fk_table_b_id_table_a1`
    FOREIGN KEY (`id_table_a`)
    REFERENCES `table_a` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);

CREATE TABLE `table_c` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `id_table_a` INT UNSIGNED NOT NULL,
  `quantity` TINYINT UNSIGNED NULL,
  PRIMARY KEY (`id`),
  INDEX `fk_table_c_id_table_a1_idx` (`id_table_a` ASC),
  CONSTRAINT `fk_table_c_id_table_a1`
    FOREIGN KEY (`id_table_a`)
    REFERENCES `table_a` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);

INSERT INTO `table_a` (`name`) VALUES ('test');
INSERT INTO `table_b` (`id_table_a`, `quantity`) VALUES ('1', '2');
INSERT INTO `table_b` (`id_table_a`, `quantity`) VALUES ('1', '4');
INSERT INTO `table_b` (`id_table_a`, `quantity`) VALUES ('1', '8');
INSERT INTO `table_c` (`id_table_a`, `quantity`) VALUES ('1', '3');
INSERT INTO `table_c` (`id_table_a`, `quantity`) VALUES ('1', '5');

【问题讨论】:

    标签: mysql sql join sum


    【解决方案1】:

    你可能会发现最好的表现是:

    SELECT a.id, a.name, 
           (SELECT SUM(b.quantity) 
            FROM table_b b
            WHERE b.id_table_a = a.id
           ) as sum_b,
           (SELECT SUM(c.quantity) 
            FROM table_c c
            WHERE c.id_table_a = a.id
           ) as sum_c
    FROM table_a a;
    

    为了提高性能,您需要在 table_b(id_table_a, quantity)table_c(id_table_a, quantity) 上建立索引。

    【讨论】:

      【解决方案2】:

      这是常见的“连接乘法”。可能的解决方案 - 在子查询中聚合单个表(对于每个聚合表)然后加入。

      SELECT a.id, a.name, sum_b, sum_c
      FROM table_a a
      LEFT JOIN ( SELECT id_table_a, SUM(quantity) sum_b
                  FROM table_b
                  GROUP BY id_table_a ) b ON b.id_table_a = a.id
      LEFT JOIN ( SELECT id_table_a, SUM(quantity) sum_c
                  FROM table_c
                  GROUP BY id_table_a ) c ON c.id_table_a = a.id;
      

      https://dbfiddle.uk/?rdbms=mysql_5.6&fiddle=32c4b2898693a21e799a84970a87b3c8

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-24
        • 2011-09-29
        • 1970-01-01
        • 1970-01-01
        • 2021-06-04
        • 2017-07-04
        • 2022-10-05
        • 1970-01-01
        相关资源
        最近更新 更多