MySql查询帮助:具有总和和计数的关节

时间:2009-03-26 21:41:39

标签: mysql join

我有这个数据库结构:

TBL_A  |  TBL_B  |  TBL_C  |  TBL_D  | TBL_E
-------+---------+---------+---------+----------
id     | id_tbla | id_tbla | id_tbla | id
name   | id_user | id_user | id_user | name_tbla
...    | is_bool |         | weight  | id_user

这是我想要实现的目标:

SELECT 
    a.id, 
    a.name, 
    b.is_bool,
    count(c.id_user) AS nb_views, 
    sum(d.weight) AS total_weight,
    count(distinct e.id_user) AS distinct_users,
FROM TBL_A AS a 
LEFT JOIN (TBL_B AS b) on (b.id_tbla = a.id)
LEFT JOIN (TBL_C AS c) on (c.id_tbla = a.id)
LEFT JOIN (TBL_D AS d) on (d.id_tbla = a.id)
LEFT JOIN (TBL_E AS e) on (e.name_tbla = a.name)
where a.id = 1 and e.id_user = 1

执行查询但结果(nb_views,total_weight,distinct_users)错误。知道为什么吗?

1 个答案:

答案 0 :(得分:1)

您尝试在一个查询中计算太多聚合。

  

Enita non sunt multiplicanda praeter necessitatem

     

(拉丁文,“实体不得超越必要性”)

您的表格B,C,D和E彼此生成Cartesian Products。假设 给出A匹配的行:

  • B
  • 中的3行
  • C中的6行
  • D
  • 中的4行
  • E
  • 中的1行

结果中的总行数为3 * 6 * 4 * 1 = 72行。因此,count(c.id_user)是你应该的12倍,你的sum(d.weight)是应该的18倍,等等。

最简单的补救措施是在单独的查询中计算每个聚合:

SELECT a.id, a.name, COALESCE(b.is_bool, FALSE) AS is_bool
FROM TBL_A AS a LEFT JOIN TBL_B AS b ON (b.id_tbla = a.id)
WHERE a.id = 1;

SELECT a.id, COUNT(c.id_user) AS nb_views
FROM TBL_A AS a LEFT JOIN TBL_C AS c ON (c.id_tbla = a.id)
WHERE a.id = 1;

SELECT a.id, SUM(d.weight) AS total_weight,
FROM TBL_A AS a LEFT JOIN TBL_D AS d ON (d.id_tbla = a.id)
WHERE a.id = 1;

SELECT a.id, COUNT(DISTINCT e.id_user) AS distinct_users,
FROM TBL_A AS a LEFT JOIN TBL_E AS e 
  ON (e.name_tbla = a.name AND e.id_user = 1)
WHERE a.id = 1;