sql - PostgreSQL:加入另一个表的计数

标签 sql postgresql join left-join

我有三个表:usersitemsboards

create table users (
    id serial primary key,
    name text
);  

create table items (
    id serial primary key,
    user_id int,
    title text
);  

create table boards (
    id serial primary key,
    user_id int,
    title text
);n

我想选择所有用户以及每个用户拥有的项目和板的数量:

select
    users.*,
    count(items) as item_count,
    count(boards) as board_count
from users
    left join items on items.user_id = users.id
    left join boards on boards.user_id = users.id
group by users.id;

不幸的是,这并没有给我正确的计数。计数比应有的高得多。发生了什么,为什么,我该如何解决?

最佳答案

问题是由两个左连接产生重复值引起的。

要解决这个问题,您可以只计算不同的值

SELECT u.id, u.name,
       COUNT(DISTINCT i.id) item_count,
       COUNT(DISTINCT b.id) board_count
  FROM users u LEFT JOIN items i
    ON u.id = i.user_id LEFT JOIN boards b
    ON u.id = b.user_id
 GROUP BY u.id, u.name

或者单独计算每个用户的项目和板,然后将它们与用户合并

SELECT u.*, 
       COALESCE(i.item_count, 0) item_count, 
       COALESCE(b.board_count, 0) board_count
  FROM users u LEFT JOIN
(
  SELECT user_id, COUNT(*) item_count
    FROM items
   GROUP BY user_id
) i ON u.id = i.user_id LEFT JOIN
(
  SELECT user_id, COUNT(*) board_count
    FROM boards
   GROUP BY user_id
) b ON u.id = b.user_id

这是 SQLFiddle 演示

关于sql - PostgreSQL:加入另一个表的计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20918509/

相关文章:

mysql - 在 JOIN 查询中使用 Match ... Against 进行相关性计算 (MySQL)

sql - Oracle 是如何进行读操作的?

postgresql - 将数据从事务表移动到历史表以提高插入性能,postgres

javascript - 如何从 Node.js API 正确发送响应代码

sql - 使用 OVER 子句和 PARTITION BY 子句与计数器计算运行总和

mysql group_concat 未知列错误

c# - 如何将子查询转换为 Join 以获得快速结果?

MYSQL删除每个GROUP超过15条的所有记录

mysql - 如何级联删除父表行

sql - Postgres 检查表行中的时间戳范围重叠