Mysql 您能否解释具有内部联接的聚合的行为

Mysql 您能否解释具有内部联接的聚合的行为,mysql,mariadb,Mysql,Mariadb,我试图理解当被聚合的列来自join子句中的表时聚合的行为 因此,我设置的场景如下: 假设某个结构具有一对多属性 class X { String[] str; int ints[]; float floats[]; } 然后由两个表表示 CREATE TABLE count_test.aggs ( inst varchar(100) NULL, id varchar(100) NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COL

我试图理解当被聚合的列来自join子句中的表时聚合的行为

因此,我设置的场景如下: 假设某个结构具有一对多属性

class X {
  String[] str;
  int ints[];
  float floats[];
}
然后由两个表表示

CREATE TABLE count_test.aggs (
    inst varchar(100) NULL,
    id varchar(100) NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

CREATE TABLE count_test.scalars (
    inst varchar(100) NULL,
    id varchar(100) NULL,
    str varchar(100) NULL,
    `int` INT NULL,
    `float` FLOAT NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;
我插入一些数据:

INSERT INTO aggs VALUES 
("inst1", "id1"),
("inst2", "id2"),
("inst3", "id3"),
("inst4", "id4"),
("inst5", "id5");

INSERT INTO scalars VALUES
('inst1', 'id1', 'str1', 1, 1.1),
('inst1', 'id1', 'str2', 2, 1.2),
('inst1', 'id1', 'str3', 3, 1.3),
('inst1', 'id1', 'str4', 4, 1.4),
('inst1', 'id1', 'str5', 5, 1.5),

('inst2', 'id2', NULL, 5, 2.1),
('inst2', 'id2', NULL, 6, 2.2),
('inst2', 'id2', NULL, 7, 2.3),
('inst2', 'id2', NULL, 7, 2.4),
('inst2', 'id2', 'str6', 8, 2.5),

('inst3', 'id3', NULL, 8, 3.1),
('inst3', 'id3', NULL, 9, 3.2),
('inst3', 'id3', NULL, 10, 3.3),
('inst3', 'id3', NULL, 11, 3.4),
('inst3', 'id3', 'str7', 12, 3.5),

('inst4', 'id4', 'str8', 13, 4.1),
('inst4', 'id4', 'str9', 14, 4.2),
('inst4', 'id4', 'str10', 15, 4.3),
('inst4', 'id4', NULL, 16, 4.4),
('inst4', 'id4', 'str7', 17, 4.5),

('inst4', 'id4', 'str8', 13, 4.1),
('inst4', 'id4', 'str9', 14, 4.2),
('inst4', 'id4', 'str10', 15, 4.3),
('inst4', 'id4', NULL, 16, 4.4),
('inst4', 'id4', 'str11', 17, 4.5),

('inst5', 'id5', 'str12', 18, 5.1),
('inst5', 'id5', 'str13', 19, 5.2),
('inst5', 'id5', 'str13', 20, 5.3),
('inst5', 'id5', 'str14', 21, 5.4),
('inst5', 'id5', 'str15', 22, 5.5);
然后我想写一个查询来查找
count
sum
avg

SELECT COUNT(s0.`str`) AS h1_c10,
 COUNT(s1.`str`) AS h1_c11,
 SUM(s2.`int`) AS h1_s10,
 SUM(s3.`float`) AS h1_s11,
 AVG(s4.`float`) AS h1_a10,
 MAX(s5.`float`) AS h1_m10,
 MIN(s6.`float`) AS h1_m11
FROM aggs h1
 INNER JOIN scalars s0 ON h1.inst = s0.inst AND h1.id = s0.id 
 INNER JOIN scalars s1 ON h1.inst = s1.inst AND h1.id = s1.id
 INNER JOIN scalars s2 ON h1.inst = s2.inst AND h1.id = s2.id
 INNER JOIN scalars s3 ON h1.inst = s3.inst AND h1.id = s3.id
 INNER JOIN scalars s4 ON h1.inst = s4.inst AND h1.id = s4.id
 INNER JOIN scalars s5 ON h1.inst = s5.inst AND h1.id = s5.id
 INNER JOIN scalars s6 ON h1.inst = s6.inst AND h1.id = s6.id
WHERE h1.inst = "inst1"
GROUP BY h1.inst, h1.id
MariaDB的结果是:

我的直觉是,
h1 X s0 X s1…X s6
的笛卡尔积正在完成,但我没有比这更多的东西了。 由于查询中的
h1.inst='inst1'
,所以我想要的(甚至是期望的)计数是5


有人能帮我理解为什么会有这样的结果,以及如何将其写入
count
sum
仅来自
scalars
的行,其中
inst='inst1'
或任何约束条件吗?

只需一个连接即可:

SELECT COUNT(s.`str`) AS h1_c10,
       COUNT(s.`str`) AS h1_c11,
       SUM(s.`int`) AS h1_s10,
       SUM(s.`float`) AS h1_s11,
       AVG(s.`float`) AS h1_a10,
       MAX(s.`float`) AS h1_m10,
       MIN(s.`float`) AS h1_m11
FROM aggs a INNER JOIN scalars s 
ON a.inst = s.inst AND a.id = s.id 
WHERE a.inst = 'inst1'
GROUP BY a.inst, a.id
但实际上,对于这个示例数据,您只需要在
标量中聚合

SELECT COUNT(s.`str`) AS h1_c10,
       COUNT(s.`str`) AS h1_c11,
       SUM(s.`int`) AS h1_s10,
       SUM(s.`float`) AS h1_s11,
       AVG(s.`float`) AS h1_a10,
       MAX(s.`float`) AS h1_m10,
       MIN(s.`float`) AS h1_m11
FROM scalars s 
WHERE s.inst = 'inst1'
GROUP BY s.inst, s.id
请参阅。
结果:


不按所选列(非聚合列)分组很可能会产生令人惊讶的结果。如果您希望在整个结果集上进行聚合,那么请省略group byhmmm,my group BY将处于禁用状态。我不清楚在这种情况下,可以使用什么GROUP BY来实现期望的结果,尽管…
inst和id
我所想的是AGG的样本数据。注意aggs id是int,scalars是varchar-在连接中测试这些有意义吗?添加了aggs的示例数据。aggs中的id是varchar,与标量中的id相同……或者我误解了您所指的内容。@zcourts您的预期输出是什么?当我看到您的评论时,您已经发布了您的答案。这就是我所期待的。我想得太多了。谢谢,我已经仔细考虑过了,虽然你的答案肯定是针对我给出的例子,但是如果连接条件不同呢。在我的问题中,假设每个内部连接s0,s1都有另一个不同的字段,因此对于我拥有的每个连接,从标量得到的行都是不同的。如何解决这一问题。我是否只需要根据唯一的连接条件编写一个查询,或者可以在一个SQL查询中表达它?代码取决于需求。发布一个带有示例数据和本案例预期结果的问题,以澄清您的需求。
> h1_c10 | h1_c11 | h1_s10 | h1_s11 | h1_a10 | h1_m10 | h1_m11
> -----: | -----: | -----: | -----: | -----: | -----: | -----:
>      5 |      5 |     15 |    6.5 |    1.3 |    1.5 |    1.1