如何过滤搜索属于已删除帖子的答案?

时间:2018-06-15 21:58:35

标签: mysql sql

我有一张这样的表:

// questions_and_answers
+----+---------------+------------------------+---------+---------+
| id |    subject    |           body         | related | deleted |
+----+---------------+------------------------+---------+---------+
| 1  | subject1      | question1              | NULL    | 0       |
| 2  |               | answer1                | 1       | 0       |
| 3  | subject2      | question2              | NULL    | 0       |
| 4  |               | answer2                | 3       | 1       |
| 5  |               | answer3                | 3       | 0       |
| 6  | subject3      | question3              | NULL    | 1       |
| 7  |               | answer4                | 6       | 0       |
+----+---------------+------------------------+---------+---------+
-- related column contains either NULL for questions or the id of its question for answers

如上表所示,answer2question3都已删除。所以我想在搜索中过滤它们。关键是,我想过滤answer4。因为它属于已删除的问题question3。知道如何进行这样的过滤?

这是我当前的查询:

SELECT qa.*
FROM questions_and_answers AS qa
WHERE MATCH(subject,body) AGAINST (:entry)
  AND deleted = 0
ORDER BY id DESC
LIMIT :page, 10;

如您所见,它仅过滤已删除的帖子。它并不关心过滤属于已删除问题的答案。

3 个答案:

答案 0 :(得分:2)

如果只有一个级别的关系 - 对于 r 的任何行, r' 存在,那么 r' .related = r .id r related IS NULL - 您可以将问题加入到答案中并检查问题deleted或使用NOT EXISTS检查是否存在已删除的父记录。

LEFT JOIN变体:

SELECT qa1.*
       FROM questions_and_answers qa1
            LEFT JOIN questions_and_answers qa2
                      ON qa2.id = qa1.related
       WHERE MATCH(qa1.subject, qa1.body) AGAINST (:entry)
             AND qa1.deleted = 0
             AND coalesce(qa2.deleted, 0) = 0
       ORDER BY qa1.id DESC
       LIMIT :page, 10;

NOT EXISTS变体:

SELECT qa1.*
       FROM questions_and_answers qa1
       WHERE MATCH(qa1.subject, qa1.body) AGAINST (:entry)
             AND qa1.deleted = 0
             AND NOT EXISTS (SELECT *
                                    FROM questions_and_answers qa2
                                    WHERE qa2.id = qa1.related
                                          AND qa2.deleted = 1)
       ORDER BY qa1.id DESC
       LIMIT :page, 10;

答案 1 :(得分:1)

好的问题和答案可能属于单独的表格;这样你就不会有这个问题。在这种情况下,您可能会在一对多关系中使用简单连接。您可以使用CTE模仿它:

1,5,9,13

如果答案显示为自己的行,那绝对必要:

with q as (
    select * from questions_and_answers
    where related is null and deleted = 0
), a as (
    select * from questions_and_answers
    where related is not null and deleted = 0
)
select *
from q left outer join a on a.related = q.related
order by q.id, a.id;

我只是意识到你在MySQL上,所以你可能没有CTE和/或分析功能。希望这对你有用。

答案 2 :(得分:0)

您可以添加另一个AND运算符,以使用相关子查询断言已删除父级的存在,并修改条件以使整体查询更加优化:

SELECT qa.*
FROM questions_and_answers AS qa
WHERE MATCH(subject,body) AGAINST (:entry)
  AND deleted = 0
  AND (qa.related IS NULL OR
    NOT EXISTS (SELECT 1
      FROM questions_and_answers qaa
      WHERE qa.related = qaa.id AND qaa.deleted = 1)
  )
ORDER BY id DESC
LIMIT :page, 10;