JOIN 两个表并得到结果

JOIN two tables and get results

我有两个 table 如下:

tbl_main
----------------------------------
id | bucket | amount 
1  |  1     | 10
2  |  2     | 10
3  |  1     | 20
4  |  4     | 10
5  |  5     | 20
6  |  6     | 30
7  |  6+    | 50
8  |  3     | 30
9  |  5     | 50

还有一个table如下

tbl_sub
----------------------------------
id | bucket | amount | status
1  |  1     | 10     |  1
2  |  1     | 10     |  1
3  |  1     | 20     |  1
4  |  4     | 10     |  2
5  |  5     | 20     |  1

我想使用桶加入这两个 tables 并在 table tbl_sub 的两个 tables 中得到每个桶的总和状态是1

预期结果是

bucket | main_amount | sub_amount
-----------------------------------
 1     |      30     |     40       
 2     |      10     |      0       
 3     |      30     |      0      
 4     |      10     |      0      
 5     |      70     |     20      
 6     |      30     |      0     
 6+    |      50     |      0      

我不明白。我哪里出错了这是我的查询

SELECT cl.bucket
     , SUM(cl.amount) as main_total
FROM `tbl_main` cl
    JOIN(SELECT bucket, SUM(amount)
         FROM `tbl_sub`
         WHERE status = '1'
         GROUP BY bucket) fl on cl.bucket = fl.bucket
 GROUP BY cl.bucket

这里的架构和 Db Fiddle link 相同

CREATE TABLE `tbl_main` ( `id` INT ,  `bucket` VARCHAR(5) ,  `amount` INT ,    PRIMARY KEY  (`id`));     

CREATE TABLE `tbl_sub` ( `id` INT  ,  `bucket` VARCHAR(5) ,  `amount` INT ,  `status` INT,    PRIMARY KEY  (`id`));


INSERT INTO `tbl_main` (`id`, `bucket`, `amount`) VALUES ('1', '1', '10'), ('2', '2', '10'), ('3','1', '20'), ('4', '4', '10'), ( '5','5', '20'), ( '6','6', '30'), ( '7','6+', '50'), ('8','3', '30'), ('9', '5', '50');


INSERT INTO `tbl_sub` (`id`, `bucket`, `amount`, `status`) VALUES ( '1','1', '10', '1'), ('2','1', '10', '1'), ('3','1', '20', '1'), ('4','4', '10', '2'), ('5','5', '20', '1');

试试这个:

使用主查询获取 main_amount 并使用子查询计算链接到主存储桶的 sub_amount,如下所示:

SELECT cl.bucket,SUM(cl.amount) as main_total,
COALESCE((SELECT SUM(s.amount) FROM `tbl_sub` s WHERE s.status='1' AND s.bucket = 
cl.bucket), 0)
FROM `tbl_main` cl
GROUP BY cl.bucket

SQL Fiddle

SQL DEMO

您需要 2 个单独的查询

SELECT t.bucket
     , t.main_total
     , COALESCE(p.sub_total, 0) as sub_total
FROM ( SELECT bucket, SUM(amount) as main_total
       FROM `tbl_main`
       GROUP BY bucket) as t
LEFT JOIN ( SELECT bucket, SUM(amount) as sub_total
       FROM `tbl_sub`
       WHERE status='1'
       GROUP BY bucket) as p
 ON t.bucket = p.bucket
ORDER BY t.bucket

您的查询有 2 处错误:

  1. 您没有使用从子查询中计算出的金额

  2. 您正在使用仅 return 匹配记录的联接 - 使用左联接从 tbl_main 获取所有内容并合并以将空值设置为零

drop table if exists t,t1;
create table t
(id int, bucket int, amount int);
insert into t values
(1  ,  1     , 10),
(2  ,  2     , 10),
(3  ,  1     , 20),
(4  ,  4     , 10),
(5  ,  5     , 20),
(6  ,  6     , 30),
(7  ,  6     , 50),
(8  ,  3     , 30),
(9  ,  5     , 50);
create table t1(id int, bucket int, amount int, status int);
insert into t1 values
(1  ,  1     , 10     ,  1),
(2  ,  1     , 10     ,  1),
(3  ,  1     , 20     ,  1),
(4  ,  4     , 10     ,  2),
(5  ,  5     , 20     ,  1);

SELECT cl.bucket
     , SUM(cl.amount) as main_total
     , coalesce(max(subamt),0) subamt
FROM t cl
left JOIN(SELECT bucket, SUM(amount) subamt
         FROM t1
         WHERE status = '1'
         GROUP BY bucket) fl on cl.bucket = fl.bucket
 GROUP BY cl.bucket;

+--------+------------+--------+
| bucket | main_total | subamt |
+--------+------------+--------+
|      1 |         30 |     40 |
|      2 |         10 |      0 |
|      3 |         30 |      0 |
|      4 |         10 |      0 |
|      5 |         70 |     20 |
|      6 |         80 |      0 |
+--------+------------+--------+
6 rows in set (0.00 sec)

这可以使用条件聚合写得不那么冗长

SELECT t.bucket
     , SUM(t.amount) as main_total
     , sum(case when t1.amount is not null and t1.status = 1 then t1.amount else 0 end )subamt
FROM t 
left join t1 on  t1.bucket = t.bucket
group by t.bucket;

您也可以,使用 with as :

with sub_tab as (SELECT bucket, SUM(amount) as sub_total
       FROM `tbl_sub`
       WHERE status='1'
       GROUP BY bucket)

SELECT t.bucket
     , SUM(t.amount) as main_total 
     , COALESCE(sub_tab.sub_total, 0) as sub_total
     from `tbl_main` t join sub_tab on 
 ON t.bucket = sub_tab.bucket
ORDER BY t.bucket