Mysql SQL二对多关系-计数记录
我有一个Mysql SQL二对多关系-计数记录,mysql,Mysql,我有一个feed表、feedComment表和feedLike表 我需要,在一个查询中,从数据库中选择所有提要,包括评论和喜欢的数量 这就是我到目前为止所做的: SELECT `feed`.`id` AS `feedID`, `feed`.`companyID`, `feed`.`eventID`, `feed`.`memberID` AS `personID`, `feed`
feed
表、feedComment
表和feedLike
表
我需要,在一个查询中,从数据库中选择所有提要,包括评论和喜欢的数量
这就是我到目前为止所做的:
SELECT
`feed`.`id` AS `feedID`,
`feed`.`companyID`,
`feed`.`eventID`,
`feed`.`memberID` AS `personID`,
`feed`.`title`,
`feed`.`text`,
`feed`.`shares`,
UNIX_TIMESTAMP(`feed`.`date`) AS `date`,
COUNT(`feedComment`.`id`) AS `comments`
FROM `feed`
LEFT JOIN `feedComment`
ON `feedComment`.`feedID` = `feed`.`id`
GROUP BY `feed`.`id`
这适用于feedComment
和feedLike
分开使用。如果我试着同时使用这两种方法,那是行不通的
我如何做到这一点?为什么不使用子查询?(至少适用于Sql Server)
如果您只需要计数,我不明白为什么要使用join鉴于目前的情况,您可以添加一个内联视图,从feedLike返回计数
SELECT `feed`.`id` AS `feedID`,
`feed`.`companyID`,
`feed`.`eventID`,
`feed`.`memberID` AS `personID`,
`feed`.`title`,
`feed`.`text`,
`feed`.`shares`,
UNIX_TIMESTAMP(`feed`.`date`) AS `date`,
IFNULL(`countLike`.`cnt`,0) AS `likes`,
COUNT(`feedComment`.`id`) AS `comments`
FROM `feed`
LEFT
JOIN `feedComment`
ON `feedComment`.`feedID` = `feed`.`id`
-- outer join to inline view (MySQL derived table)
LEFT
JOIN (
SELECT `feedLike`.`feedID`
, COUNT(`feedLike`.`id`) AS `cnt`
FROM `feedLike`
GROUP BY `feedLike`.`feedID`
) `countLike`
ON `countLike`.`feedID` = `feed`.`id`
GROUP BY `feed`.`id`
将执行参数之间的查询,结果将是MySQL所称的“派生表”。我们为该派生表指定一个名称<代码>计数式。对于外部查询,它就像countLike
是一个实际的表
在外部选择中使用IFNULL()
函数将可能的空值替换为零。我们这样做并不是强制性的,但通常人们喜欢得到一个“零”作为计数返回,而不是一个空值
请注意,派生表可能存在严重的性能问题。(最新版本的MySQL解决了其中一些问题,例如派生表上缺少索引。)
同样的方法也可用于从feedComment
表中获取计数。特别是如果没有其他需要按feed.id
分组的情况下
SELECT feed.id AS `feedID`
, feed.companyID
, feed.eventID
, feed.memberID AS `personID`
, feed.title
, feed.text
, feed.shares
, UNIX_TIMESTAMP(feed.date) AS `date`
, IFNULL(countLike.cnt,0) AS `likes`
, IFNULL(countComment.cnt,0) AS `comments`
FROM feed
LEFT
JOIN ( SELECT c.feedID
, COUNT(1) AS cnt
FROM feedComment c
GROUP BY c.feedID
) countComment
ON countComment.feedID = feed.id
LEFT
JOIN ( SELECT l.feedID
, COUNT(1) AS cnt
FROM feedLike l
GROUP BY l.feedID
) countLike
ON countLike.feedID = feed.id
清晰的 作为一种完全不同的方法,您可以让查询生成部分叉积(对于与
FeedComment
中的每一行相匹配的给定feedID,FeedLike中的每一行),然后计算“distinct”id
值。但这种方法有可能产生相当大的中间结果(而且会导致性能下降)。(如果给定的feed
有30行feedLike
和feedComment
中的30行,则单个feed总共有1 x 30 x 30=900行
我有意将此示例保留为不完整的示例,以阻止将其作为一般做法。但我之所以将其包括在内,是因为它确实演示了另一种方法:
SELECT feed.id
, ...
, COUNT(DISTINCT feedLike.ID)
, COUNT(DISTINCT feedComment.ID)
FROM feed
LEFT
JOIN feedLike
ON ...
LEFT
JOIN feedComment
ON ...
GROUP BY feed.id
在加入之前,使用内联视图查找计数,然后加入。你能给我一个例子吗?谢谢你的清晰回答和漂亮的解释!
SELECT feed.id
, ...
, COUNT(DISTINCT feedLike.ID)
, COUNT(DISTINCT feedComment.ID)
FROM feed
LEFT
JOIN feedLike
ON ...
LEFT
JOIN feedComment
ON ...
GROUP BY feed.id