Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL自连接以仅查找下一个修订版_Mysql_Sql_Self Join - Fatal编程技术网

MySQL自连接以仅查找下一个修订版

MySQL自连接以仅查找下一个修订版,mysql,sql,self-join,Mysql,Sql,Self Join,实际上我在和Wordpress合作。我想创建一个自连接或类似的东西来查找一篇文章的修订版,以及同一篇文章的后续修订版 create table wp_posts (post_id int, revision_id int); INSERT INTO wp_posts(post_id, revision_id) VALUES (1, 1); INSERT INTO wp_posts(post_id, revision_id) VALUES (1, 2); INSERT INTO wp_posts(

实际上我在和Wordpress合作。我想创建一个自连接或类似的东西来查找一篇文章的修订版,以及同一篇文章的后续修订版

create table wp_posts (post_id int, revision_id int);
INSERT INTO wp_posts(post_id, revision_id) VALUES (1, 1);
INSERT INTO wp_posts(post_id, revision_id) VALUES (1, 2);
INSERT INTO wp_posts(post_id, revision_id) VALUES (1, 3);

INSERT INTO wp_posts(post_id, revision_id) VALUES (2, 11);
INSERT INTO wp_posts(post_id, revision_id) VALUES (2, 12);
INSERT INTO wp_posts(post_id, revision_id) VALUES (2, 13);

SELECT a.post_id, a.revision_id "PreviousRevision", b.revision_id "FollowingRevision"
  FROM `wp_posts` a
  JOIN `wp_posts` b
    ON a.post_id = b.post_id   #the id of every revision of a post is different but the post_id is the same
 WHERE a.revision_id < b.revision_id
 AND a.revision_id != b.revision_id
上一个查询不起作用,因为它需要对a的每个记录进行所有修改,而不仅仅是下一个修改

这就是我得到的,我已经删除了我不想要的线条。我只需要父子行


如何只获取一个元素?

在MySQL 8+中,您将使用窗口函数:

SELECT p.post_id, p.revision_id,
       lag(p.revision_id) over (partition by p.post_id order by p.revision_id) as prev_revision_id,
       lead(p.revision_id) over (partition by p.post_id order by p.revision_id) as next_revision_id
FROM `wp_posts` p;
在早期版本中,我将使用相关子查询:

select p.post_id, p.revision_id,
       (select max(p2.revision_id)
        from wp_posts p2
        where p2.post_id = p.post_id and p2.revision_id < p.revision_id
       ) as prev_revision_id,
       (select min(p2.revision_id)
        from wp_posts p2
        where p2.post_id = p.post_id and p2.revision_id > p.revision_id
       ) as next_revision_id
from wp_posts p;

对于此示例数据,您需要a.post\u id和b.revision\u id的每个组合的最大a.revision\u id:


我不会将@forpas中的查询与group by一起使用,因为我不喜欢查询的explain看起来像是临时+文件排序

在这种情况下,我通常会这样做:

SELECT 
    a.post_id
  , a.revision_id "PrevRevision"
  , b.revision_id "NextRevision"
FROM
    `wp_posts` AS a
    INNER JOIN `wp_posts` AS b ON (
            b.post_id = a.post_id
        AND b.revision_id > a.revision_id
    )
    LEFT JOIN `wp_posts` AS c ON (
            c.post_id = a.post_id
        AND c.revision_id > a.revision_id
        AND c.revision_id < b.revision_id
    )
WHERE
    c.revision_id IS NULL

在某些数据集上,@Gordon Linoff建议的查询子查询会更快。

谢谢,我无法理解为什么group by有效。。你能帮我吗?在这方面:你可以不分组就看到结果。正如您所看到的,对于a.post_id、b.revision_id的每个组合,您希望在结果中显示a.revision_id的最大值。这是GROUP BY和MAX所做的。非常聪明的解决方案我不能同时接受这两个答案,但这也是非常重要的great@Revious . . . 使用窗口函数的版本显然性能更好。我希望相关子查询也比聚合解决方案快。
| post_id | PreviousRevision | FollowingRevision |
| ------- | ---------------- | ----------------- |
| 1       | 1                | 2                 |
| 1       | 2                | 3                 |
| 2       | 11               | 12                |
| 2       | 12               | 13                |
SELECT 
    a.post_id
  , a.revision_id "PrevRevision"
  , b.revision_id "NextRevision"
FROM
    `wp_posts` AS a
    INNER JOIN `wp_posts` AS b ON (
            b.post_id = a.post_id
        AND b.revision_id > a.revision_id
    )
    LEFT JOIN `wp_posts` AS c ON (
            c.post_id = a.post_id
        AND c.revision_id > a.revision_id
        AND c.revision_id < b.revision_id
    )
WHERE
    c.revision_id IS NULL
id  select_type table   partitions  type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  a       index   IX_wp_post_idx  IX_wp_post_idx  10      6   100.00  Using where; Using index
1   SIMPLE  b       ref IX_wp_post_idx  IX_wp_post_idx  5   test.a.post_id  4   33.33   Using where; Using index
1   SIMPLE  c       ref IX_wp_post_idx  IX_wp_post_idx  5   test.a.post_id  4   16.67   Using where; Using index