[英]Query with NOT IN subquery returning 0 rows
我遇到了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]现在带有更新的sqlfiddle
基于已编辑问题中提供的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
疯狂
首先,我不知道您要使用此查询实现什么,但是我将在这里告诉您查询的问题。
在第二部分中,您使用以下查询:
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
子句在分组依据之前检查postid。
您需要更改脚本的逻辑。
这里的问题看起来非常简单。 让我们分解一下您的陈述:
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
部分中,您说的是:
“返回所有结果,其中c.private=0
”
然后,当然可以将它们从外部结果中删除。
因此,这里发生的是:
a)您将返回外部语句中的所有记录b) NOT IN
将基于相同的WHERE
条件返回所有语句c)每行匹配时,您当然得到零结果
听起来您需要将子查询修改为您不希望看到的内容。
省略未使用的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
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.