PostgreSQL多表连接方法及三类用户/项目统计查询实现
没问题!我来帮你搞定这三个SQL查询,顺便把PostgreSQL里多表连接的常用方式给你讲清楚~
首先咱们得先明确T2的结构,因为你只给了T1的字段,而查询里用到了nb_hour_interv和nb_interv,我假设T2表包含以下核心字段:user_id、project、nb_hour_interv、nb_interv(和T1的关联键是user_id,如果需要按项目维度精准匹配,会额外关联project字段,下面我会两种情况都覆盖到)。
1. 按用户统计nb_hour_doc与nb_hour_interv的总和
如果只按用户维度统计(不区分项目),用user_id关联两张表即可:
SELECT t1.user_id, t1.user_name, COALESCE(SUM(t1.nb_hour_doc), 0) AS total_nb_hour_doc, COALESCE(SUM(t2.nb_hour_interv), 0) AS total_nb_hour_interv, COALESCE(SUM(t1.nb_hour_doc), 0) + COALESCE(SUM(t2.nb_hour_interv), 0) AS total_hours FROM T1 t1 LEFT JOIN T2 t2 ON t1.user_id = t2.user_id GROUP BY t1.user_id, t1.user_name ORDER BY t1.user_id;
👉 小说明:
- 用
LEFT JOIN是为了保留T1里所有用户,哪怕T2里没有该用户的数据(这时候T2字段会是NULL,COALESCE能把NULL转成0,避免求和结果为空)。 - 如果只需要统计同时存在于T1和T2的用户,把
LEFT JOIN换成INNER JOIN就行。
如果需要按用户+项目维度精准统计(确保同一个用户的同一项目数据对应),只需在关联条件里加上project:
SELECT t1.user_id, t1.user_name, t1.project, COALESCE(SUM(t1.nb_hour_doc), 0) AS total_nb_hour_doc, COALESCE(SUM(t2.nb_hour_interv), 0) AS total_nb_hour_interv, COALESCE(SUM(t1.nb_hour_doc), 0) + COALESCE(SUM(t2.nb_hour_interv), 0) AS total_hours FROM T1 t1 LEFT JOIN T2 t2 ON t1.user_id = t2.user_id AND t1.project = t2.project GROUP BY t1.user_id, t1.user_name, t1.project ORDER BY t1.user_id, t1.project;
2. 按用户统计nb_doc与nb_interv的总和
这个和第一个查询逻辑完全一致,只是把求和字段换成nb_doc和nb_interv:
SELECT t1.user_id, t1.user_name, COALESCE(SUM(t1.nb_doc), 0) AS total_nb_doc, COALESCE(SUM(t2.nb_interv), 0) AS total_nb_interv, COALESCE(SUM(t1.nb_doc), 0) + COALESCE(SUM(t2.nb_interv), 0) AS total_items FROM T1 t1 LEFT JOIN T2 t2 ON t1.user_id = t2.user_id GROUP BY t1.user_id, t1.user_name ORDER BY t1.user_id;
同样,如果需要按用户+项目维度统计,在关联条件里加上project即可。
3. 按项目统计nb_hour_doc与nb_hour_interv的总和
按项目维度统计时,分组键换成project,同时要考虑项目只存在于某一张表的情况:
SELECT COALESCE(t1.project, t2.project) AS project, -- 避免项目名出现NULL COALESCE(SUM(t1.nb_hour_doc), 0) AS total_nb_hour_doc, COALESCE(SUM(t2.nb_hour_interv), 0) AS total_nb_hour_interv, COALESCE(SUM(t1.nb_hour_doc), 0) + COALESCE(SUM(t2.nb_hour_interv), 0) AS total_hours FROM T1 t1 FULL OUTER JOIN T2 t2 ON t1.project = t2.project GROUP BY COALESCE(t1.project, t2.project) ORDER BY project;
👉 小说明:
- 用
FULL OUTER JOIN是为了保留所有项目,不管是只在T1还是只在T2里的。如果只需要统计同时存在于两张表的项目,换成INNER JOIN;如果只保留T1里的项目,用LEFT JOIN。 COALESCE(t1.project, t2.project)是为了避免项目名出现NULL(比如某个项目只在T2里,t1.project就会是NULL)。
多表连接的常见实现方式
PostgreSQL里常用的连接类型有这几种,你可以根据需求选:
- INNER JOIN:只返回两张表中满足关联条件的行,相当于取交集。
- LEFT JOIN(LEFT OUTER JOIN):返回左表(JOIN左边的表)的所有行,右表满足条件的行匹配,不满足则右表字段为NULL。
- RIGHT JOIN(RIGHT OUTER JOIN):和LEFT JOIN相反,返回右表的所有行,左表匹配的行对应,不满足则左表字段为NULL。
- FULL OUTER JOIN:返回左表和右表的所有行,匹配的行合并,不匹配的另一方字段为NULL,相当于取并集。
关联条件一般用ON子句指定(比如ON t1.user_id = t2.user_id),如果是同名字段,也可以用USING(user_id)简化写法。
内容的提问来源于stack exchange,提问作者Vashia
相关产品推荐
相关产品推荐

