我正在尝试一次从三个表中检索数据。表格如下:
类别
id
category
messageid
消息
id
title
message
评论
id
messageid
message
我想要获得的是1条消息(因为我有一个基于id WHERE
的{{1}}子句),3个类别(因为有3个类别链接到消息)和2条评论(因为有2条评论与消息相关联。)
我正在尝试通过以下查询检索数据:
3
但是,在运行此查询时,我得到6个结果:
SELECT categories.category, messages.id, messages.title, messages.message, comments.count, comments.id as commentid, comments.message as commentmessage
FROM categories
RIGHT JOIN
(SELECT id, title, message
FROM messages WHERE messaged.id = 3) messages
ON messages.id = categories.messageid
LEFT JOIN
(SELECT count(id), id, message
FROM comments
GROUP BY id, message) comments
ON messages.id = comments.messageid
ORDER BY article.id DESC
我期望结果如下:
category id title message count commentid commentmessage
test 3 the title the message 1 6 comment 1
test 3 the title the message 1 5 comment 2
installation 3 the title the message 1 6 comment 1
installation 3 the title the message 1 5 comment 2
question 3 the title the message 1 6 comment 1
question 3 the title the message 1 5 comment 2
只有三行我应该能够获得所有需要的数据。这甚至可能吗?我完全错了吗?
答案 0 :(得分:7)
这里有几个问题,如评论中所述。
首先,由于您要加入三个表,因此您得到的答案是正确的。 1 x 2 x 3行= 6.
其次,您的评论汇总并没有真正汇总任何内容。正如您在结果中看到的那样,计数总是一个,当我希望您认为两个评论时它是2。由于您正在对ID进行分组,因此将为每个唯一ID执行计数,该ID始终为1。我想你可能想在messageid上分组
SELECT count(*), messageid
FROM comments
GROUP BY messageid
您需要进行另一次加入或单独查询才能自行获取评论。
同样如评论中所述,您通常不会以这种方式获取信息;你通常只做三个查询,因为两个关系是一对多的。如果您的类别很短(并且您正在使用SQL Server),您可以将类别压缩到它们自己的列中(即“测试,安装,问题”)。以下是你将如何做到这一点。
select id, title, message,
(select CAST(category + ', ' as nvarchar(max))
from @Categories c where messageid = m.id
for xml path('')) as Categories
from @Messages m
where m.id = 3
实际上,有几种方法可以做到这一点,但这很快就很脏。那么你只需要一个额外的评论查询。您可以加入上一个查询,并将所有信息分成两行,如下所示
select m.id, title, m.message,
(select CAST(category + ', ' as nvarchar(max))
from @Categories c where messageid = m.id
for xml path('')) as Categories,
cm.message
from @Messages m
left outer join @Comments cm on m.id = cm.messageid
where m.id = 3
但是,您可能只想进行额外的查询以避免重复信息。
最后,我想展示你可能想要进行评论计数。
select m.id, title, m.message,
(select CAST(category + ', ' as nvarchar(max))
from @Categories c where messageid = m.id
for xml path('')) as Categories,
CommentCount,
cm.message
from @Messages m
left outer join
(
select messageid, COUNT(*) CommentCount
from @Comments
group by messageid
) rsCommentCount on rsCommentCount.messageid = m.id