0

次のような MySQL テーブルがあります。

ID    elementName  subElementOfID

1        1            
2        2            
3        4            
4        5            
5        9            
6        3            
7        6            
8        7            
9       71            8
10       8            
11      10            
12      72            8
13      73            8

要素は必ずしも数値ではありませんが、varchar にすることができます。列 "subElementOfID" は、この要素 (たとえば "71") が ID X の要素のサブ要素であることを意味します。この例では、ID 9、12、および 13 の要素は、ID 8 の要素のサブ要素です。

目標:

サブ要素としてマークされた要素を親要素のすぐ下に並べて、このテーブルを数字または英数字の順序で並べます (これは依存しますが、それほど重要ではありません)。この場合、番号順に並べられた SELECT 出力は次のようになります。

ID    elementName  subElementOfID

 1        1            
 2        2            
 6        3            
 3        4            
 4        5            
 7        6            
 8        7            
 9       71            8
12       72            8
13       73            8
10        8            
 5        9            
11       10            

出力は、後で PHP で処理されます。PHPソリューションではなく、正しい順序でテーブルを提供するSQL-Selectを使用することをお勧めします。

どんな助けやアドバイスも大歓迎です。

これは私の最初の Stackoverflow の質問なので、すべての重要な事実を収集し、さらに情報を提供する準備ができていることを願っています :-)

ラルフ


SELF JOIN と UNION を含む解決策を見つけました。これは非常に複雑かもしれないので、もっと簡単な SELECT が欲しいです。

SELECT ID, element FROM 
((SELECT t1.ID, t1.elementName as element, t2.elementName AS element2, t1.subElementOfID 
FROM test t1
LEFT JOIN test t2 ON t2.ID = t1.subElementOfID
WHERE t1.subElementOfID IS NOT NULL)

UNION

(SELECT ID, elementName AS element, elementName AS element2, subElementOfID FROM test 
WHERE subElementOfID IS NULL)

ORDER BY element2, subElementOfID, element) tu

ユーザー xpda (ご入力ありがとうございます!) は、文字列連結による順序付けを提案しました。elementName 列に数字ではなく名前が実際に含まれている場合、これは実際には素晴らしいアイデアだと思います。数字の英数字の順序に完全に満足しているわけではないからです。実生活では、この列に整数を入れていますが、上司に数字ではなく口頭での名前を使用するよう説得するかもしれません。xpdaの答えを理解した上でSQL式を書き込もうとしています:

SELECT t1.ID, t1.elementName, t1.subElementOfID AS parentName
FROM test2 t1
LEFT JOIN test2 t2 ON t1.subElementOfID=t2.ID
ORDER BY IF(ISNULL(t2.elementName), t1.elementName, CONCAT(CAST(t2.elementName AS CHAR), CAST(t1.elementName AS CHAR)));

したがって、すべての子要素は親の下に並べられますが、「10」は当然 1 と 2 の間です...

さらに提案はありますか?

4

2 に答える 2

1

2 つの列 (2 列目 + 1 列目) を連結して並べ替え (並べ替え) ることができます。最初に文字列に変換する必要がある場合があります。

于 2013-02-23T21:06:31.363 に答える
0

わかりました、私は自分の質問に答えるつもりです:-) Barmarからのコメントは、xpdaからの答えと同様に役に立ちました。彼らはSQLを提供しませんでしたが、私を正しい方向に導きました。どうもありがとうございました!

私には2つの実用的なソリューションがあり、それぞれにメリットがあります。

  1. 単純な自己結合を作成し、連結された文字列で順序付けします。この文字列は、1桁の数値の先行ゼロで強化されています。その他の場合(varchar値をソートする場合)、これらのゼロは必要ありません。

    SELECT t1.ID, t1.elementName, t1.subElementOfID AS parentName
    FROM table t1
    LEFT JOIN table t2 ON t1.subElementOfID=t2.ID
    ORDER BY IF(ISNULL(t2.elementName), LPAD(t1.elementName, 2, '0'), CONCAT(CAST(LPAD(t2.elementName, 2, '0') AS CHAR), CAST(t1.elementName AS CHAR)));
    
  2. 自己結合とUNIONを使用した上記のSQLは、少し長くても正常に機能します。

    SELECT ID, element FROM 
    ((SELECT t1.ID, t1.elementName as element, t2.elementName AS element2, t1.subElementOfID 
    FROM table t1
    LEFT JOIN table t2 ON t2.ID = t1.subElementOfID
    WHERE t1.subElementOfID IS NOT NULL)
    
    UNION
    
    (SELECT ID, elementName AS element, elementName AS element2, subElementOfID FROM table
    WHERE subElementOfID IS NULL)
    
    ORDER BY element2, subElementOfID, element) tu
    
于 2013-02-24T15:24:12.463 に答える