1

MySQL データベースには、国、町、町内のエリアがすべて「mailshot」テーブルに含まれています。内部結合を使用して、粒度の降順でセット全体を返したいと思います。実際には、ユーザーがドロップダウン リストを表示して、国、町、または町内のエリアを選択できるようにしたいと考えています。

データは次のようになります。

mailshot_id mailshot_parent mailshot_name mailshot_level
49 0 イングランド 0
56 0 スコットランド 0
140 49 ロンドン 1
149 49 ヨーク 1
191 56 グラスゴー 1
300 140 ウィンブルドン 2
310 140 ウェストミンスター 2
493 56 エディンバラ 1

そして、私はそれを次のように出力したい:

mailshot_id mailshot_parent mailshot_name mailshot_level
49 0 イングランド 0
149 49 ヨーク 1
140 49 ロンドン 1
300 140 ウィンブルドン 2
310 140 ウェストミンスター 2
56 0 スコットランド 0
191 56 グラスゴー 1
493 56 エディンバラ 1


私はこれでほとんどそれを手に入れました:

選択する
    p_idとしてp.mailshot_id、
    p.mailshot_name を p_name として、
    p_levelとしてp.mailshot_level、
    p.mailshot_parent として p_parent、
    c.mailshot_id を c_id として、
    c.mailshot_parent として c_parent として、
    c.mailshot_level c_levelとして、
    c.mailshot_name を c_name として、
    場合
        p.mailshot_parent = 0 THENの場合
        p.mailshot_id
        そうしないと
        p.mailshot_parent
    END AS calcOrder
から
    メールショット p LEFT JOIN メールショット c
    ON p.mailshot_id = c.mailshot_parent
ORDER BY calcOrder , p_id "

しかし、孫レコード (レベル 2) を子レコード (レベル 1) の近くにグループ化していません。「ケース」の部分が間違っているに違いないと思います。でもそれなら考えられない。

助言がありますか?前もって感謝します。

4

2 に答える 2

1

残念ながら、MySQL は階層クエリをサポートしていません (START WITH...CONNECT BY または CTE に相当するものはありません)。そのため、これを困難で醜い方法で行う必要があります。

以下は 3 つのレベルで機能しますが、ツリーをさらに深くする必要がある場合はかなり面倒です。ここにフィドルがあります

SELECT  C.MAILSHOT_ID
        ,C.MAILSHOT_PARENT
        ,C.MAILSHOT_NAME
        ,C.MAILSHOT_LEVEL
        ,CASE   WHEN C.MAILSHOT_LEVEL = 0 
                THEN CAST(C.MAILSHOT_ID AS CHAR(4))
                WHEN C.MAILSHOT_LEVEL = 1 
                THEN CONCAT(CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4)))
                ELSE CONCAT(CAST(P.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4)))
        END AS SORT_ORDER    
FROM    MAILSHOT C
LEFT OUTER JOIN
        MAILSHOT P
ON      P.MAILSHOT_ID = C.MAILSHOT_PARENT       
ORDER BY CASE   WHEN C.MAILSHOT_LEVEL = 0 
                THEN CAST(C.MAILSHOT_ID AS CHAR(4))
                WHEN C.MAILSHOT_LEVEL = 1 
                THEN CONCAT(CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4)))
                ELSE CONCAT(CAST(P.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4)))
        END
于 2013-08-06T18:19:40.877 に答える
1

これは階層テーブルの典型的な例であり、Oracle でクエリを実行する方が簡単ですが、それは重要ではありません。@Declan_K は、あなたが望むものを達成するための良い答えをくれました。適切に整理された出力でわずかに異なる代替手段を探している場合は、次のアプローチを試すことができます。

SELECT m1.mailshot_name AS lev1n ,           
       m1.mailshot_id AS lev1,
       m1.mailshot_parent AS lev1p,
       m2.mailshot_name AS lev2n,
       m2.mailshot_id AS lev2,
       m2.mailshot_parent AS lev2p,
       m3.mailshot_name lev3n,
       m3.mailshot_id lev3,
       m3.mailshot_parent AS lev3p
FROM mailshot m1
LEFT JOIN mailshot m2 ON m2.mailshot_parent = m1.mailshot_id
LEFT JOIN mailshot m3 ON m3.mailshot_parent = m2.mailshot_id
WHERE m1.mailshot_parent = 0;

出力を与えます:

+----------+------+-------+-----------+------+-------+-------------+------+-------+
| lev1n    | lev1 | lev1p | lev2n     | lev2 | lev2p | lev3n       | lev3 | lev3p |
+----------+------+-------+-----------+------+-------+-------------+------+-------+
| England  |   49 |     0 | London    |  140 |    49 | Wimbledon   |  300 |   140 |
| England  |   49 |     0 | London    |  140 |    49 | Westminster |  310 |   140 |
| England  |   49 |     0 | York      |  149 |    49 | NULL        | NULL |  NULL |
| Scotland |   56 |     0 | Glasgow   |  191 |    56 | NULL        | NULL |  NULL |
| Scotland |   56 |     0 | Edinburgh |  493 |    56 | NULL        | NULL |  NULL |
+----------+------+-------+-----------+------+-------+-------------+------+-------+

MySQL で階層データを処理する方法の概要は、http:
//mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
http://explainextended.com/2009/03/17/にあります。 mysql の階層クエリ/

于 2013-08-06T18:36:49.133 に答える