SQL рекурсивно фильтрует результаты, чтобы исключить 3 самые последние записи для каждого соответствующего поля - PullRequest
1 голос
/ 20 марта 2019

У меня есть данные, где записи будут иметь общее значение parent.Я хотел бы вернуть все ожидаемые записи для трех последних записей для каждого parent.

Например, мои данные для начала выглядят примерно так:

----------------------------------------------
| ID     | post_date           | post_parent |
----------------------------------------------
| 326524 | 2018-08-17 14:48:09 |        1576 |
| 326693 | 2018-08-18 12:49:10 |        1576 |
| 326694 | 2018-08-18 13:04:21 |        1576 |
| 326695 | 2018-08-18 13:05:02 |        1576 |
| 326749 | 2018-08-19 19:30:33 |        1576 |
| 326752 | 2018-08-19 19:39:43 |        1576 |
| 19340  | 2011-05-28 10:38:46 |       19323 |
| 19344  | 2011-05-28 10:40:10 |       19323 |
| 19345  | 2011-05-28 10:42:12 |       19323 |
| 19347  | 2011-05-28 10:45:53 |       19323 |
| 19349  | 2011-05-28 10:49:53 |       19323 |
| 19350  | 2011-05-28 10:52:40 |       19323 |
| 19351  | 2011-05-28 10:55:45 |       19323 |
| 19352  | 2011-05-28 10:55:58 |       19323 |
| 19353  | 2011-05-28 10:57:46 |       19323 |
| 161381 | 2016-10-26 10:53:52 |       19323 |
| 161417 | 2016-10-26 12:15:56 |       19323 |
| 161418 | 2016-10-26 12:16:31 |       19323 |
| 163912 | 2016-11-10 14:24:11 |       19323 |
| 163914 | 2016-11-10 14:28:24 |       19323 |
| 163954 | 2016-11-10 16:35:51 |       19323 |
| 163956 | 2016-11-10 16:39:54 |       19323 |
| 163959 | 2016-11-10 16:43:32 |       19323 |
| 321095 | 2018-07-29 10:44:54 |       19323 |
| 321097 | 2018-07-27 17:28:09 |       19323 |
| 321135 | 2018-07-29 10:45:59 |       19323 |
| 321136 | 2018-07-29 10:57:00 |       19323 |
----------------------------------------------

Я хотел бы в итоге:

----------------------------------------------
| ID     | post_date           | post_parent |
----------------------------------------------
| 326524 | 2018-08-17 14:48:09 |       1576  |
| 326693 | 2018-08-18 12:49:10 |       1576  |
| 326694 | 2018-08-18 13:04:21 |       1576  |
| 19340  | 2011-05-28 10:38:46 |      19323  |
| 19344  | 2011-05-28 10:40:10 |      19323  |
| 19345  | 2011-05-28 10:42:12 |      19323  |
| 19347  | 2011-05-28 10:45:53 |      19323  |
| 19349  | 2011-05-28 10:49:53 |      19323  |
| 19350  | 2011-05-28 10:52:40 |      19323  |
| 19351  | 2011-05-28 10:55:45 |      19323  |
| 19352  | 2011-05-28 10:55:58 |      19323  |
| 19353  | 2011-05-28 10:57:46 |      19323  |
| 161381 | 2016-10-26 10:53:52 |      19323  |
| 161417 | 2016-10-26 12:15:56 |      19323  |
| 161418 | 2016-10-26 12:16:31 |      19323  |
| 163912 | 2016-11-10 14:24:11 |      19323  |
| 163914 | 2016-11-10 14:28:24 |      19323  |
| 163954 | 2016-11-10 16:35:51 |      19323  |
| 163956 | 2016-11-10 16:39:54 |      19323  |
| 163959 | 2016-11-10 16:43:32 |      19323  |
| 321097 | 2018-07-27 17:28:09 |      19323  |
----------------------------------------------

Сначала я попробовал что-то вроде

sql

select a.post_type
     , a.ID
     , a.post_parent
     , a.post_date
     , b.ID as parent_id
     , b.post_type as parent_post_type
     , b.post_status as parent_status 
  from wp_posts a 
  join wp_posts b 
 where a.post_type = 'revision' 
   and a.post_date > '2018-03-20' 
   and a.post_parent = b.id 
   and b.post_status = 'publish' 
   AND a.post_parent NOT IN (select post_parent 
                               from wp_posts 
                              where post_parent = 1576 
                                and post_type = 'revision' 
                              ORDER 
                                 BY post_date DESC 
                              LIMIT 3)

Но реализовано 2 проблемы:

  1. LIMIT не поддерживается в предложении IN
  2. Даже еслиэто было так, LIMIT в моем запросе вернул бы всего 3 сообщения, а не 3 для каждого родителя сообщения.

Я предполагаю, что следующим шагом будет разбить это на цикл php и выполнитьтам, но мне любопытно, если бы я мог осуществить это в SQL!

Ответы [ 2 ]

0 голосов
/ 20 марта 2019

Вы можете использовать функцию окна. Это работает в MySQL v8.0 , но, возможно, не в более ранней версии.

with temp as (
    select 
        ID,
        post_date,
        post_parent,
        row_number() over (partition by post_parent order by post_date desc) rankno
    from table_name
)

select *
from temp
where rankno > 3;
0 голосов
/ 20 марта 2019

Вы можете сделать это с помощью подзапроса. , , но без использования in:

select pr.post_type, pr.ID, pr.post_parent, pr.post_date,
       pp.ID as parent_id, pp.post_type as parent_post_type, pp.post_status as parent_status 
from wp_posts pr inner join
     wp_posts pp 
     on pr.post_parent = pp.id 
where pr.post_type = 'revision' and apr.post_date > '2018-03-20' and 
      pp.post_status = 'publish' and
      pr.post_date <= coalesce( (select p2.post_date
                                 from wp_posts
                                 where p2.post_parent = pr.post_parent and
                                       p2.post_type = 'revision' 
                                 order by p2.post_date desc
                                 limit 1, 2
                                ), pr.post_date
                               );

Основная идея заключается в том, что вы можете использовать скалярный подзапрос с <. Я думаю, что я исправил запрос, чтобы сделать то, что вы хотите, а также ввел разумные псевдонимы таблиц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...