我有这个数据库结构:
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)错误。知道为什么吗?
答案 0 :(得分:1)
您尝试在一个查询中计算太多聚合。
Enita non sunt multiplicanda praeter necessitatem
(拉丁文,“实体不得超越必要性”)
您的表格B,C,D和E彼此生成Cartesian Products。假设 给出A匹配的行:
结果中的总行数为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;