LEFT JOIN 中的 COUNT 返回重复值
COUNT in LEFT JOIN returning duplicated value
我有下表(示例):
用户:
id | user | photo | joined | country
1 | Igor | abc.jpg | 2015 | Brazil
2 | John | cga.png | 2014 | USA
3 | Lucas| hes.jpg | 2016 | Japan
posts(看到有两行author = Igor
和ft = 2
和一行author = Igor
和ft = 3
和 Igor 有三个帖子):
id | author | content | date | ft (2 = photos and 3 = videos)
1 | Igor | hi | 2016 | 2
2 | Igor | hello | 2016 | 3
3 | John | hehehe | 2016 | 2
4 | Igor | huhuhuh | 2016 | 2
5 | Lucas | lol | 2016 | 3
友谊(当status = 2
表示他们是朋友时):
id | friend1 | friend2 | status
1 | Igor | Lucas | 2
2 | Lucas | John | 2
3 | John | Igor | 2
我想与 ft = 2
和 COUNT
个朋友 (status = 2
) 一起发 COUNT
个 帖子根据当前登录的用户(在本例中为 Igor)。
所以,我这样做(假设当前登录的用户是Igor):
SELECT photo, joined, country, sum(CASE WHEN ft = 2 THEN 1 ELSE 0 END) AS numPhotos, sum(CASE WHEN ft = 3 THEN 1 ELSE 0 END) AS numVideos
FROM users
LEFT JOIN posts
ON users.user = posts.author
WHERE users.user = 'Igor'
GROUP BY users.user
LIMIT 1
当我检查 foreach
时,数据是正确的:
numPhotos = 2
和 numVideos = 1
.
但是,我也想select好友的数量,所以,我这样做:
SELECT photo, joined, country, sum(CASE WHEN ft = 2 THEN 1 ELSE 0 END) AS numPhotos, sum(CASE WHEN ft = 3 THEN 1 ELSE 0 END) AS numVideos, count(friendship.status) AS numFriends
FROM users
LEFT JOIN posts
ON users.user = posts.author
LEFT JOIN friendship
ON (users.user = friend1 OR users.user = friend2) AND friendship.status = 2
WHERE users.user = 'Igor'
GROUP BY users.user
LIMIT 1
但是,输出是:
numPhotos = 4
、numVideos = 2
和 numFriends = 6
。
换句话说,他复制了所有结果,但在 numFriends
中,他获取了 Igor (3) 的帖子总数并复制了值。如果我将 count(friendship.status)
更改为 sum(friendship.status)
,则输出为:
numPhotos = 4
、numVideos = 2
和 numFriends = 18
(numFriends
的三倍)。
我也用 count(distinct friendship.status)
试过,结果是:
numPhotos = 4
、numVideos = 2
和 numFriends = 1
(再次重复这些值以及 return 错误的值 1 对于 numFriends
应该是 2 知道他有两个朋友) .
那么,我该怎么做呢? (我正在使用 MySQL)
编辑:
我将 count(distinct friendship.status)
更改为 count(distinct friendship.id)
,它对 select 好友数量有效。但其余值(numPhotos
和 numVideos
)继续重复。
我发现问题出在 ON (users.user = friend1 OR users.user = friend2)
,因为如果我只保留 ON (users.user = friend1)
或 ON (users.user = friend2)
,则输出不会重复。我也尝试使用 ON 'Igor' IN (friend1, friend2) but the result is the same (
numPhotosand
numVideos` continue duplicated)。
尝试使用 count(distinct friendship.id)
而不是 count(distinct friendship.status)
。那应该给你独特的朋友的数量。计算不同的状态不起作用,因为根据定义所有状态都是 2,因此只有一个不同的值。
我认为左联接可能是在一对多关系上联接,这会导致计数膨胀。
由于您只检索 1 个用户的计数,我建议使用子查询来检索友谊计数(对于检索多个用户的计数,派生的 table 可能比子查询更快):
SELECT
sum(ft = 2) AS numPhotos,
sum(ft = 3) AS numVideos,
(select count(*) from friendships f
where (friend1 = users.user
or friend2 = users.user)
and status = 2) as friendship_count
FROM users
LEFT JOIN posts
ON users.user = posts.author
WHERE users.user = 'Igor'
请注意,我删除了 group by
,因为 users.user
已经在 where 子句中,这意味着只有 1 个组。
我有下表(示例):
用户:
id | user | photo | joined | country
1 | Igor | abc.jpg | 2015 | Brazil
2 | John | cga.png | 2014 | USA
3 | Lucas| hes.jpg | 2016 | Japan
posts(看到有两行author = Igor
和ft = 2
和一行author = Igor
和ft = 3
和 Igor 有三个帖子):
id | author | content | date | ft (2 = photos and 3 = videos)
1 | Igor | hi | 2016 | 2
2 | Igor | hello | 2016 | 3
3 | John | hehehe | 2016 | 2
4 | Igor | huhuhuh | 2016 | 2
5 | Lucas | lol | 2016 | 3
友谊(当status = 2
表示他们是朋友时):
id | friend1 | friend2 | status
1 | Igor | Lucas | 2
2 | Lucas | John | 2
3 | John | Igor | 2
我想与 ft = 2
和 COUNT
个朋友 (status = 2
) 一起发 COUNT
个 帖子根据当前登录的用户(在本例中为 Igor)。
所以,我这样做(假设当前登录的用户是Igor):
SELECT photo, joined, country, sum(CASE WHEN ft = 2 THEN 1 ELSE 0 END) AS numPhotos, sum(CASE WHEN ft = 3 THEN 1 ELSE 0 END) AS numVideos
FROM users
LEFT JOIN posts
ON users.user = posts.author
WHERE users.user = 'Igor'
GROUP BY users.user
LIMIT 1
当我检查 foreach
时,数据是正确的:
numPhotos = 2
和 numVideos = 1
.
但是,我也想select好友的数量,所以,我这样做:
SELECT photo, joined, country, sum(CASE WHEN ft = 2 THEN 1 ELSE 0 END) AS numPhotos, sum(CASE WHEN ft = 3 THEN 1 ELSE 0 END) AS numVideos, count(friendship.status) AS numFriends
FROM users
LEFT JOIN posts
ON users.user = posts.author
LEFT JOIN friendship
ON (users.user = friend1 OR users.user = friend2) AND friendship.status = 2
WHERE users.user = 'Igor'
GROUP BY users.user
LIMIT 1
但是,输出是:
numPhotos = 4
、numVideos = 2
和 numFriends = 6
。
换句话说,他复制了所有结果,但在 numFriends
中,他获取了 Igor (3) 的帖子总数并复制了值。如果我将 count(friendship.status)
更改为 sum(friendship.status)
,则输出为:
numPhotos = 4
、numVideos = 2
和 numFriends = 18
(numFriends
的三倍)。
我也用 count(distinct friendship.status)
试过,结果是:
numPhotos = 4
、numVideos = 2
和 numFriends = 1
(再次重复这些值以及 return 错误的值 1 对于 numFriends
应该是 2 知道他有两个朋友) .
那么,我该怎么做呢? (我正在使用 MySQL)
编辑:
我将 count(distinct friendship.status)
更改为 count(distinct friendship.id)
,它对 select 好友数量有效。但其余值(numPhotos
和 numVideos
)继续重复。
我发现问题出在 ON (users.user = friend1 OR users.user = friend2)
,因为如果我只保留 ON (users.user = friend1)
或 ON (users.user = friend2)
,则输出不会重复。我也尝试使用 ON 'Igor' IN (friend1, friend2) but the result is the same (
numPhotosand
numVideos` continue duplicated)。
尝试使用 count(distinct friendship.id)
而不是 count(distinct friendship.status)
。那应该给你独特的朋友的数量。计算不同的状态不起作用,因为根据定义所有状态都是 2,因此只有一个不同的值。
我认为左联接可能是在一对多关系上联接,这会导致计数膨胀。 由于您只检索 1 个用户的计数,我建议使用子查询来检索友谊计数(对于检索多个用户的计数,派生的 table 可能比子查询更快):
SELECT
sum(ft = 2) AS numPhotos,
sum(ft = 3) AS numVideos,
(select count(*) from friendships f
where (friend1 = users.user
or friend2 = users.user)
and status = 2) as friendship_count
FROM users
LEFT JOIN posts
ON users.user = posts.author
WHERE users.user = 'Igor'
请注意,我删除了 group by
,因为 users.user
已经在 where 子句中,这意味着只有 1 个组。