Идея для написания запроса mysql

У меня есть таблица с именем wp_bp_activity со многими столбцами, и я думаю, что я должен работать с 4 из них для этой проблемы: id , type , item_id и date_recorded .

1 – Когда кто-то отправляет новую активность, typeactivity_update а item_id0

2 – Когда кто-то item_id новый комментарий к активности, его typeactivity_comment а item_id – идентификатор активности в идентификаторе столбца

3 – В обоих случаях date_recorded является датой date_recorded данных.

В таблице также больше type s.

Но я хочу получить только строки с type activity_update что кто-то недавно ответил или был новым (на основе date_recorded я думаю)

Я пробовал:

 SELECT a.*, b.* FROM wp_bp_activity as a, wp_bp_activity as b WHERE ((b.type = 'activity_update') OR (b.type = 'activity_comment' AND b.item_id = a.id)) order by cast(a.date_recorded as datetime) desc limit 0,20 

Это занимает слишком много времени для выполнения и заканчивается недостаточной ошибкой памяти.

Любая помощь по этому типу запросов оценена.

Обновление # 1

  wp_bp_activity table id type item_id date_recorded |---------|-----------------------|-----------|-------------------------- | 12081 | activity_comment | 12079 | 2013-10-18 07:27:01 |---------|-----------------------|-----------|-------------------------- | 12080 | activity_update | 0 | 2013-10-18 07:26:40 |---------|-----------------------|-----------|-------------------------- | 12079 | activity_update | 0 | 2013-10-17 05:15:43 

Какие строки, которые я хочу получить из этой таблицы, – это идентификаторы в этом порядке:

 12079 12080 

То, чего я не хочу получать:

Тип activity_comment

В каком порядке должны появляться строки?

Поскольку вы можете видеть, что строка с типом activity_comment имеет item_id со значением 12079 . так что 12079 – это последнее мероприятие, которое недавно кто-то прокомментировал, а 12080 не имеет комментариев, а только что опубликован. Поэтому я хочу обоих, но при этом порядке:

 12079 12080 

Я предполагаю, что вы ищете «последние записи» ( WHERE type = 'activity_update' AND date_recorded > [threshold] ) и «записи, имеющие последний ответ, независимо от возраста записи» ( WHERE reply.type = 'activity_comment' AND reply.date_recorded > [threshold] ).

Первый набор прост:

 SELECT entries.* FROM activity AS entries WHERE type = 'activity_update' AND date_recorded > [threshold] 

Второй набор немного менее очевиден:

 SELECT entries.* FROM activity AS entries JOIN activity AS replies ON replies.item_id = entries.id AND replies.type = 'activity_comment' WHERE entries.type = 'activity_update' AND replies.date_recorded > [threshold] 

Объединяя все это:

 SELECT entries.* FROM activity AS entries LEFT JOIN activity AS replies -- LEFT JOIN, because an INNER JOIN would filter out entries without any reply ON replies.item_id = entries.id AND replies.type = 'activity_comment' WHERE entries.type = 'activity_update' AND ( entries.date_recorded > [threshold] OR replies.date_recorded > [threshold] -- evaluates as FALSE if replies.date_recorded is NULL ) ORDER BY IFNULL(replies.date_recorded, entries.date_recorded) -- replies if not null, entries otherwise 

Я не горжусь своим плохо выполняющим предложением ORDER BY , я надеюсь, что кто-то может предложить лучшую идею

Вы должны добавить еще одно поле

 id, type, item_id, commented_on, date_recorded 

::->> commented_on будет оправдывать комментарии item_id на commented_on , здесь 12079 комментариев на 12080, так что вам может легко получить то, что вы хотите

Таким образом, ваша структура должна выглядеть так:

  id type commented_on item_id date_recorded |---------|-----------------------|-----------|-----------|-------------------------- | 12081 | activity_comment | 12080 | 12079 | 2013-10-18 07:27:01 |---------|-----------------------|-----------|-----------|-------------------------- | 12080 | activity_update | 0 | 0 | 2013-10-18 07:26:40 |---------|-----------------------|-----------|-----------|-------------------------- | 12079 | activity_update | 0 | 0 | 2013-10-17 05:15:43 

Может быть, мне не хватает чего-то огромного, но что не так?

 SELECT * FROM `wp_bp_activity` WHERE `type`='activity_update' ORDER BY `date_recorded` ASC LIMIT 0, 20; 

У вас есть условие JOIN в предложении OR. Это отличный пример того, почему вы не должны использовать этот синтаксис.

 SELECT a.*, b.* FROM wp_bp_activity as a JOIN wp_bp_activity as b ON b.item_id = a.id WHERE ((b.type = 'activity_update') OR (b.type = 'activity_comment')) order by cast(a.date_recorded as datetime) desc limit 0,20