php - 前のクエリの値を使用してより多くの結果を取得する

原文 php mysql sql mysqli

私はこのようなテーブルを持っています:

+---------+----------+
| post_id | reply_to |
+---------+----------+
|       1 |        0 |
|       2 |        1 |
|       3 |        2 |
|       4 |        2 |
|       5 |        3 |
|       6 |        5 |
|       7 |        1 |
|       8 |        7 |
|       9 |        8 |
|      10 |        7 |
+---------+----------+


reply_toは単に返信されている投稿のIDです(つまり、post_idの2はpost_idの1への返信です)。

入れ子形式にすると次のようになります。

1
    2
        3
            5
                6
        4
    7
        8
            9
        10


次のことを行う単一のクエリを作成するにはどうすればよいですか。


クエリ1:post_id = 1(2 and 7)への返信であるすべての投稿を取得し、結果の数を5に制限する
クエリ2:クエリ1から取得した値を使用して、子投稿(3 and 48 and 10)を取得し、結果の数を親投稿あたり3に制限します
クエリ3:クエリ2から取得した値を使用して、子投稿(5および9)を取得し、結果の数を親投稿ごとに1つに制限します


したがって、最終的に、結果には次のpost_idが含まれるはずです:2, 3, 5, 4, 7, 8, 9, 10

ここに私が作成したSQLフィドルがあります:http://sqlfiddle.com/#!2/23edc/21

助けてください!
答え
これはSQL Serverで機能し、汎用のSQLだと思いますが、SQL Fiddleを今すぐ機能させることができません。

create table test1 (post_id int, reply_to int);

insert into test1 (post_id, reply_to) values
(1,0),(2,1),(3,2),(4,2),(5,3),(6,5),(7,1),(8,7),(9,8),(10,7),
(11,2),(12,2),(13,2),(14,3); /* Added records to test conditions */

/* All replies to post_id=1 */
with q1 as (
    select post_id
    from test1
    where reply_to = 1
)
/* Top 3 replies to all results in q1 */
, q2 as (
    select
            q1.post_id as parent_post,
            t1.post_id as child_post,
            count(*) as row_num
    from test1 as t1
        inner join q1 on t1.reply_to = q1.post_id
        left outer join test1 as t2 on t1.reply_to = t2.reply_to 
                and t1.post_id >= t2.post_id
    group by q1.post_id, t1.post_id
    having count(*) <= 3
)
/* Get 0 or 1 grandchild posts */
, q3 as (
    select
            q2.parent_post,
            q2.child_post,
            t1.post_id as grandchild_post,
            count(*) as row_num
    from q2
        left outer join test1 as t1 on q2.child_post = t1.reply_to
        left outer join test1 as t2 on t1.reply_to = t2.reply_to 
                and t1.post_id >= t2.post_id
    group by q2.parent_post, q2.child_post, t1.post_id
    having count(*) = 1
)
/* Aggregate the different post ids */
select distinct parent_post as post_id from q3
union
select distinct child_post from q3
union
select distinct grandchild_post from q3 
        where grandchild_post is not null;

drop table test1;
関連記事

php - php mysql jQueryによる連鎖選択

php - ISO 8601の日付/時刻がHTTP経由で送信され、PHPのDateTimeオブジェクトに作成されたときのエラー

php - 列の結果を変数に格納する

nginx - Nginx + php-fpmでファイルが見つかりません

php - mysqlでの結合操作とともに、3つの列(city + streetaddress + state)の値に基づいて類似の住所レコードを選択します

php - mod_rewrite:複数のパラメーターを持つフォームURLを短いパラメーターに変換します(中間部分なし)

php - 更新時の検証の誤動作

php - このMySQL外部選択がクエリの速度を低下させる理由を理解する

php - Modxのユーザー拡張フィールドにデフォルト値を設定する

php - PHP / MySQLiの複数のSQLオブジェクト