我有一个feed
表,feedComment
表和feedLike
表。
我需要在一个查询中选择数据库中包含评论和喜欢数量的所有Feed。
这是我到目前为止所做的:
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
分开。如果我尝试同时使用它们,它就不起作用。
我如何做到这一点?
答案 0 :(得分:1)
为什么不使用subquerys? (至少在Sql Server上运行)
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`,
(Select count(`feedComment`.`id`) from feedComment Where commentid = F.id) as 'Comment',
(Select count('feedLike'.'id') from feedLike Where likeid = F.id) as 'Something else'
From feed F
如果您只是需要计数,我不明白为什么要使用加入
答案 1 :(得分:1)
根据您目前所拥有的内容,您可以添加内联视图以从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`
将执行parens之间的查询,结果将是MySQL所谓的"派生表"。我们为派生表分配了一个名称...... countLike
。对于外部查询,它就像countLike
一样是一个真正的表。
在外部选择中使用IFNULL()
函数来将可能的NULL值替换为零。我们这样做不是强制性的,但通常人们喜欢得到一个零"作为计数返回,而不是NULL。
请注意,派生表可能会出现严重的性能问题。 (最新版本的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
<强> DISTINCT 强>
作为一种完全不同的方法,您可以让查询生成部分跨产品(FeedLike
的每一行,对于与FeedComment
的每一行匹配的给定FeedID),然后计算&# 34个不同的&#34; id
值。但是这种方法有可能产生相当大的(和性能杀死)中间结果。 (如果给定的feed
在feedLike
中有30行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