You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL统计同时关联sentences和vocabulary的topics数量 解决关联计数错误

问题原因说明

你原有查询计数不准的核心原因是对两个关联表同时JOIN时会产生笛卡尔积:比如某topic下有3条符合条件的sentences、2条符合条件的vocabulary,JOIN后会生成3*2=6条中间数据,直接count(s.id)、count(v.id)得到的结果都是6,和实际数量不符。


解决方案

1. 简单修改版(适合小数据量场景)

用DISTINCT对关联表的主键去重后计数即可:

SELECT
  t.id AS topic_id,
  COUNT(DISTINCT s.id) AS total_sentences,
  COUNT(DISTINCT v.id) AS total_vocabulary
FROM topics t
LEFT JOIN sentences s 
  ON s.topic_id = t.id AND s.locale_id = 1
LEFT JOIN vocabulary v 
  ON v.topic_id = t.id AND v.locale_id = 1
GROUP BY t.id
-- 筛选同时存在两类关联数据的topic
HAVING total_sentences > 0 AND total_vocabulary > 0
ORDER BY t.id;

2. 高性能明细输出版(适合大数据量场景)

提前对两个关联表做单独聚合,再和topics表关联,避免产生笛卡尔积冗余数据:

SELECT 
  t.id AS topic_id,
  s.cnt AS total_sentences,
  v.cnt AS total_vocabulary
FROM topics t
-- 先统计每个topic的sentences数量
INNER JOIN (
  SELECT topic_id, COUNT(id) AS cnt
  FROM sentences
  WHERE locale_id = 1
  GROUP BY topic_id
) s ON s.topic_id = t.id
-- 再统计每个topic的vocabulary数量
INNER JOIN (
  SELECT topic_id, COUNT(id) AS cnt
  FROM vocabulary
  WHERE locale_id = 1
  GROUP BY topic_id
) v ON v.topic_id = t.id
ORDER BY t.id;

该方案用INNER JOIN自动过滤了只有单表关联数据的topic,不需要额外加筛选条件,执行效率更高。

3. 最高性能计数版(仅需要统计符合条件的topic总数量时使用)

如果不需要输出每个topic的具体关联数量,直接用EXISTS查询性能最优:

SELECT COUNT(*) AS qualified_topic_count
FROM topics t
WHERE EXISTS (
  SELECT 1 FROM sentences s 
  WHERE s.topic_id = t.id AND s.locale_id = 1
) AND EXISTS (
  SELECT 1 FROM vocabulary v 
  WHERE v.topic_id = t.id AND v.locale_id = 1
);

内容的提问来源于stack exchange,提问作者user3871

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 06:45:02