簡體   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