sql 来自多个表的 count()
sql count() from multiple tables
有这样的表格:
图片:
wall_id|picture_id|user_id|likes
1| 1| 1| 2
1| 2| 1| 0
2| 1| 1| 1
2| 2| 2| 2
对 (wall_id, picture_id) 是唯一的
喜欢的人:
wall_id|picture_id|user_id
1| 1| 3
1| 1| 2
2| 1| 2
2| 2| 4
2| 2| 3
我想要这样的东西:
user_id|pictures_count|likes_count|likers_count
1| 3| 3| 2
2| 1| 2| 2
我试过这个:
select p.user_id as user_id,
count(p.user_id) as pictures_count,
sum(p.likes) as likes_count,
count(distinct l.user_id) as likers_count
from pictures p
left join likers l on p.wall_id = l.wall_id
and p.picture_id = l.picture_id
group by p.user_id
和
select pictures.user_id, count(pictures.user_id) as pictures_count,
sum(pictures.likes) as likes_count,
count(distinct likers.user_id) as likers_count
from pictures, likers
where pictures.picture_id = likers.picture_id
and pictures.user_id = likers.user_id
group by pictures.user_id
但我得到这样的结果:
user_id|pictures_count|likes_count|likers_count
1| 4| 6| 2
2| 2| 4| 2
我应该怎么做才能得到正确的结果?
A join
会导致行重复。您可以在加入之前应用聚合。
select *
from (
select wall_id
, sum(likes) as likes_count
, count(*) as picture_count
from pictures
group by
wall_id
) as pictures
left join
(
select wall_id
, count(distinct user_id) as likers_count
from likers
group by
wall_id
) as likes
on pictures.wall_id = likes.wall_id
Join
是奇怪的东西。当您有一个键并且多行在 both 边匹配时,您会得到更多您期望的行。解决方案是预先聚合每一侧的行。
这对于您的数据模型来说有点复杂,因为您需要 join
来查找 likes
table.
的用户 ID
select p.user_id as user_id, p.pictures_count, p.likes_count, l.likers_count
from (select p.user_id, count(*) as pictures_count, sum(likes) as likes_count
from pictures p
group by p.user_id
) p left join
(select p.user_id, count(distinct l.user_id) as likers_count
from pictures p left join
likers l
on p.wall_id = l.wall_id and p.picture_id = l.picture_id
group by p.user_id
) l
on p.user_id = l.user_id;
请注意,因为聚合是在子查询中完成的,所以在外部查询中不再需要它。
试试这个:
SELECT T1.user_id,T1.pictures_count,T1.likes_count,T2.likers_count FROM
(select p.user_id,
count(*) AS pictures_count,
SUM(p.likes) as likes_count
from pictures p
group by p.user_id) T1 JOIN
(select p.user_id,count(distinct l.user_id) as likers_count
from pictures p join
likers l on p.wall_id = l.wall_id and p.picture_id = l.picture_id
group by p.user_id) T2 on T1.user_id=T2.user_id
结果:
USER_ID PICTURES_COUNT LIKES_COUNT LIKERS_COUNT
1 3 3 2
2 1 2 2
在 SQL Fiddle 中查看结果。
有这样的表格:
图片:
wall_id|picture_id|user_id|likes 1| 1| 1| 2 1| 2| 1| 0 2| 1| 1| 1 2| 2| 2| 2
对 (wall_id, picture_id) 是唯一的
喜欢的人:
wall_id|picture_id|user_id 1| 1| 3 1| 1| 2 2| 1| 2 2| 2| 4 2| 2| 3
我想要这样的东西:
user_id|pictures_count|likes_count|likers_count
1| 3| 3| 2
2| 1| 2| 2
我试过这个:
select p.user_id as user_id,
count(p.user_id) as pictures_count,
sum(p.likes) as likes_count,
count(distinct l.user_id) as likers_count
from pictures p
left join likers l on p.wall_id = l.wall_id
and p.picture_id = l.picture_id
group by p.user_id
和
select pictures.user_id, count(pictures.user_id) as pictures_count,
sum(pictures.likes) as likes_count,
count(distinct likers.user_id) as likers_count
from pictures, likers
where pictures.picture_id = likers.picture_id
and pictures.user_id = likers.user_id
group by pictures.user_id
但我得到这样的结果:
user_id|pictures_count|likes_count|likers_count
1| 4| 6| 2
2| 2| 4| 2
我应该怎么做才能得到正确的结果?
A join
会导致行重复。您可以在加入之前应用聚合。
select *
from (
select wall_id
, sum(likes) as likes_count
, count(*) as picture_count
from pictures
group by
wall_id
) as pictures
left join
(
select wall_id
, count(distinct user_id) as likers_count
from likers
group by
wall_id
) as likes
on pictures.wall_id = likes.wall_id
Join
是奇怪的东西。当您有一个键并且多行在 both 边匹配时,您会得到更多您期望的行。解决方案是预先聚合每一侧的行。
这对于您的数据模型来说有点复杂,因为您需要 join
来查找 likes
table.
select p.user_id as user_id, p.pictures_count, p.likes_count, l.likers_count
from (select p.user_id, count(*) as pictures_count, sum(likes) as likes_count
from pictures p
group by p.user_id
) p left join
(select p.user_id, count(distinct l.user_id) as likers_count
from pictures p left join
likers l
on p.wall_id = l.wall_id and p.picture_id = l.picture_id
group by p.user_id
) l
on p.user_id = l.user_id;
请注意,因为聚合是在子查询中完成的,所以在外部查询中不再需要它。
试试这个:
SELECT T1.user_id,T1.pictures_count,T1.likes_count,T2.likers_count FROM
(select p.user_id,
count(*) AS pictures_count,
SUM(p.likes) as likes_count
from pictures p
group by p.user_id) T1 JOIN
(select p.user_id,count(distinct l.user_id) as likers_count
from pictures p join
likers l on p.wall_id = l.wall_id and p.picture_id = l.picture_id
group by p.user_id) T2 on T1.user_id=T2.user_id
结果:
USER_ID PICTURES_COUNT LIKES_COUNT LIKERS_COUNT
1 3 3 2
2 1 2 2
在 SQL Fiddle 中查看结果。