1

いくつかのQAフォーラム(たとえば、stackoverflow)のMYSQLに、次のサンプルデータを含むテーブル「posts」があります。

    INSERT INTO POSTS (postID, type, parentID, QuesTitle) VALUES(1,'Q',NULL,'sometext');
    INSERT INTO POSTS (postID, type, parentID, QuesTitle) VALUES(2,'Q',NULL,'randomtext');
    INSERT INTO POSTS (postID, type, parentID, QuesTitle) VALUES(3,'A',1,NULL);
    INSERT INTO POSTS (postID, type, parentID, QuesTitle) VALUES(4,'A',1,NULL);
    INSERT INTO POSTS (postID, type, parentID, QuesTitle) VALUES(5,'Q',NULL,'titletext');
    INSERT INTO POSTS (postID, type, parentID, QuesTitle) VALUES(6,'A',1,NULL);
    INSERT INTO POSTS (postID, type, parentID, QuesTitle) VALUES(7,'A',2,NULL);
    INSERT INTO POSTS (postID, type, parentID, QuesTitle) VALUES(8,'A',2,NULL);

postIDは主キーであり、parentIDはpostIDを参照します。「Q」(質問)タイプの投稿には、複数の「A」(回答)投稿(parentIDで表示)を含めることができます。「Q」の投稿にのみタイトルがありますが、「A」の投稿にはタイトルがありません(NULL)

「A」タイプの投稿を、投稿ID、親ID、およびそれが参照するQuestitleとともに選択したいと思います。たとえば-必要な結果は-

    postID    parentID    QuesTitle
    3         1           sometext
    4         1           sometext
    6         1           sometext
    7         2           randomtext
    8         2           randomtext

'with'句CTEを使用する方が簡単ですが、MYSQLはそれをサポートしていません。誰かがMYSQLでそれを達成するのを手伝ってくれますか?

4

2 に答える 2

3

彼らの例では、なぜCTEを使用したいかは明確ではないかもしれませんが、MySQLがこの非常に不足している機能を追加するのは本当に素晴らしいことだと私は同意します(ヒントヒントMariaDBファンデーション)

CTEは、任意の深さの階層データに非常に役立ちます。

これがpostgresの例です:

CREATE TABLE posts (
    postid integer,
    type character varying(100),
    parentid integer,
    questitle character varying(100)
);
INSERT INTO posts VALUES (1, 'Q', NULL, 'sometext');
INSERT INTO posts VALUES (2, 'Q', NULL, 'randomtext');
INSERT INTO posts VALUES (3, 'A', 1, NULL);
INSERT INTO posts VALUES (4, 'A', 1, NULL);
INSERT INTO posts VALUES (5, 'Q', NULL, 'titletext');
INSERT INTO posts VALUES (6, 'A', 1, NULL);
INSERT INTO posts VALUES (7, 'A', 2, NULL);
INSERT INTO posts VALUES (8, 'A', 2, NULL);
INSERT INTO posts VALUES (9, 'A', 8, NULL);
INSERT INTO posts VALUES (10, 'A', 4, NULL);
INSERT INTO posts VALUES (11, 'A', 10, NULL);
INSERT INTO posts VALUES (12, 'A', 11, NULL);

次のクエリで:

with recursive posts_cte (postid, type, parentid, questitle,level,id_lineage)  as
(
    -- base case
    select 
        postid, type, parentid, questitle, 0 as level, ''||postid as id_lineage
    from 
        POSTS
    where 
        parentid is null

    UNION ALL

    -- recursion case
    select 
        c.postid, c.type, c.parentid, c.questitle, p.level+1 as level, p.id_lineage||','||c.postid as id_lineage
    from
        posts c
        inner join posts_cte p on
            c.parentid = p.postid
)
select
    postid, type, parentid, questitle,level,id_lineage
from
    posts_cte
order by
    id_lineage;

結果セットを生成します。

 postid | type | parentid | questitle  | level |  id_lineage
--------+------+----------+------------+-------+--------------
      1 | Q    |          | sometext   |     0 | 1
      3 | A    |        1 |            |     1 | 1,3
      4 | A    |        1 |            |     1 | 1,4
     10 | A    |        4 |            |     2 | 1,4,10
     11 | A    |       10 |            |     3 | 1,4,10,11
     12 | A    |       11 |            |     4 | 1,4,10,11,12
      6 | A    |        1 |            |     1 | 1,6
      2 | Q    |          | randomtext |     0 | 2
      7 | A    |        2 |            |     1 | 2,7
      8 | A    |        2 |            |     1 | 2,8
      9 | A    |        8 |            |     2 | 2,8,9
      5 | Q    |          | titletext  |     0 | 5
于 2013-02-07T19:34:40.387 に答える
1

なぜCTEが必要なのですか?

自己参加を行うだけで、parentIDの情報を取得できます。

SELECT a.postID, a.parentID, b.QuesTitle
FROM   posts a
JOIN   posts b ON a.parentID = b.postID
WHERE  a.type = 'A'
于 2012-07-28T08:59:21.473 に答える