我遇到了一个SQL查询问题,理想情况下应该将所有评论都返回给论坛中的一个帖子。
现在我有以下问题:
SELECT p.*, 'BBCode' AS Format,
FROM_UNIXTIME(TIME) AS DateInserted,
FROM_UNIXTIME(editTime) AS DateUpdated
FROM et_post p
LEFT JOIN et_conversation c ON c.conversationId = p.conversationId
WHERE c.private = 0
AND p.postId NOT IN (
SELECT p.postId
FROM et_conversation c
LEFT JOIN et_post p ON p.conversationId = c.conversationId WHERE c.private = 0
GROUP BY p.conversationId
ORDER BY p.TIME
)
然而,这会返回0行。我希望它能够返回8800行。
如果我单独运行第一部分:
SELECT p.*, 'BBCode' AS Format,
FROM_UNIXTIME(TIME) AS DateInserted,
FROM_UNIXTIME(editTime) AS DateUpdated
FROM et_post p
LEFT JOIN et_conversation c ON c.conversationId = p.conversationId
WHERE c.private = 0
输出:
# postId, conversationId, memberId, time, editMemberId, editTime, deleteMemberId, deleteTime, title, content, attributes, Format, DateInserted, DateUpdated
'12', '5', '1', '1436600657', NULL, NULL, NULL, NULL, '', 'Content1', ?, 'BBCode', '2015-07-11 09:44:17', NULL
'13', '5', '1', '1436600681', NULL, NULL, NULL, NULL, 'Testing area', 'Content2', ?, 'BBCode', '2015-07-11 09:44:41', NULL
'14', '5', '1', '1436600698', NULL, NULL, NULL, NULL, 'Testing area', 'Content 3', ?, 'BBCode', '2015-07-11 09:44:58', NULL
'15', '5', '19', '1436602065', NULL, NULL, NULL, NULL, 'Testing area', 'More content', ?, 'BBCode', '2015-07-11 10:07:45', NULL
'16', '5', '19', '1436602093', NULL, NULL, NULL, NULL, 'Testing area', 'Even more content', ?, 'BBCode', '2015-07-11 10:08:13', NULL
'17', '5', '1', '1436602137', NULL, NULL, NULL, NULL, 'Testing area', 'Will it ever stop?', ?, 'BBCode', '2015-07-11 10:08:57', NULL
'54', '5', '1', '1436617274', NULL, NULL, NULL, NULL, 'Testing area', 'Ah, final one..', ?, 'BBCode', '2015-07-11 14:21:14', NULL
它返回9304行,如上所述,这听起来是正确的。
单独运行子查询:
SELECT p.postId
FROM et_conversation c
LEFT JOIN et_post p ON p.conversationId = c.conversationId WHERE c.private = 0
GROUP BY p.conversationId
ORDER BY p.TIME
输出:
# postId
'12'
'18'
'19'
'44'
'70'
'73'
'75'
它给了我如上所述的412行,这听起来也是正确的。
理想情况下,我对最终查询的输出应如下所示:
# postId, conversationId, memberId, time, editMemberId, editTime, deleteMemberId, deleteTime, title, content, attributes, Format, DateInserted, DateUpdated
'13', '5', '1', '1436600681', NULL, NULL, NULL, NULL, 'Testing area', 'Content2', ?, 'BBCode', '2015-07-11 09:44:41', NULL
'14', '5', '1', '1436600698', NULL, NULL, NULL, NULL, 'Testing area', 'Content 3', ?, 'BBCode', '2015-07-11 09:44:58', NULL
'15', '5', '19', '1436602065', NULL, NULL, NULL, NULL, 'Testing area', 'More content', ?, 'BBCode', '2015-07-11 10:07:45', NULL
'16', '5', '19', '1436602093', NULL, NULL, NULL, NULL, 'Testing area', 'Even more content', ?, 'BBCode', '2015-07-11 10:08:13', NULL
'17', '5', '1', '1436602137', NULL, NULL, NULL, NULL, 'Testing area', 'Will it ever stop?', ?, 'BBCode', '2015-07-11 10:08:57', NULL
'54', '5', '1', '1436617274', NULL, NULL, NULL, NULL, 'Testing area', 'Ah, final one..', ?, 'BBCode', '2015-07-11 14:21:14', NULL
(注意postId 12已经消失)
[编辑] 从一些快速的计算中我得出以下事实:根据返回的行数,以下查询听起来正确:
SELECT p.*, 'BBCode' AS Format,
FROM_UNIXTIME(TIME) AS DateInserted,
FROM_UNIXTIME(editTime) AS DateUpdated
FROM et_post p
INNER JOIN et_conversation c ON c.conversationId = p.conversationId
WHERE c.private = 1
AND p.postId NOT IN (
SELECT DISTINCT po.conversationId
FROM et_post po
);
[EDIT2] 现在有一个sqlfiddle
基本上,我希望ID为12,15和18的行不见了,因为它们是由开始对话的人创建的原始帖子。
[EDIT3] 现在有一个updated sqlfiddle
答案 0 :(得分:1)
根据已编辑问题中提供的SQLFiddle,这可行。
SELECT p.*, 'BBCode' AS Format,
FROM_UNIXTIME(TIME) AS DateInserted,
FROM_UNIXTIME(editTime) AS DateUpdated
FROM et_post p
INNER JOIN et_conversation c
ON c.conversationId = p.conversationId
and c.private = 0
join (
select conversationId,min(postId) as m
from et_post
group by conversationId
) r
on r.conversationId = c.conversationId
where p.postId<>r.m
12,15,18消失按照您的编辑要求... NOT IN
疯狂
答案 1 :(得分:0)
首先,我不知道你试图用这个查询实现什么,但我会告诉你这里的查询有什么问题..
在第二部分中,您使用以下查询:
SELECT p.postId
FROM et_conversation c
LEFT JOIN et_post p ON p.conversationId = c.conversationId WHERE c.private = 0
GROUP BY p.conversationId
ORDER BY p.TIME
如果你单独运行它,它会给出以下结果:
12,15,18
现在删除Order by和Group by子句。查询现在是:
SELECT p.postId
FROM et_conversation c
LEFT JOIN et_post p ON p.conversationId = c.conversationId WHERE c.private = 0
如果您运行此查询,则会得到结果:
12,13,14,15,16,17,18,19,20
这些都是postid的。 在对它们进行分组之前,sql忽略了所有这些post id。 因为您的Group by子句在逻辑上是错误的。您正在对列进行分组并选择另一个在此情况下不唯一的列。
不管。问题是,NOT IN
子句正在检查分组前的位置。
您需要更改脚本的逻辑。
答案 2 :(得分:0)
这里的问题看起来很简单。让我们打破你的陈述:
SELECT p.*, 'BBCode' AS Format,
FROM_UNIXTIME(TIME) AS DateInserted,
FROM_UNIXTIME(editTime) AS DateUpdated
FROM et_post p
LEFT JOIN et_conversation c ON c.conversationId = p.conversationId
WHERE c.private = 0
AND p.postId NOT IN (
SELECT p.postId
FROM et_conversation c
LEFT JOIN et_post p ON p.conversationId = c.conversationId WHERE c.private = 0
GROUP BY p.conversationId
ORDER BY p.TIME
)
在第一部分中,您将从et_post表和et_conversation表中提取所有行c.private = 0
没有其他条款。
然后在NOT IN
部分,您要说:
&#34;返回c.private=0
&#34;
当然,它会将它们从外部结果中删除。
所以这里发生的事情是:
a)您将返回外部声明中的所有记录
b)NOT IN
基于SAME WHERE
条件返回所有语句
c)每行匹配,当然得到零结果
听起来您需要将子查询修改为您不想看到的内容。
答案 3 :(得分:-1)
省略未使用的et_conversations
:
SELECT p.*
, 'BBCode' AS Format
, FROM_UNIXTIME(TIME) AS DateInserted
, FROM_UNIXTIME(editTime) AS DateUpdated
FROM et_post p
WHERE EXISTS ( -- suppress the first one
SELECT 1
FROM et_post x
WHERE x.postid = p.postid
AND x.TIME < p.TIME
);