繁体   English   中英

使用NOT IN子查询返回0行的查询

[英]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并非100%正确-因此是此更新版本。

基于已编辑问题中提供的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM