[英]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.