これは、以前の質問のより高度な続編です。
これは、物事を少し明確にするための SQLFiddle へのリンクです
(場所ごとに) 次のようなものを返す必要があります。
1 階
---------------
ガレージ
- ラジエーター
キッチン
- 炊飯器
- 冷蔵庫
これよりもさらに多くのレベルがありますが、始めることができれば、必要に応じてさらに進んでいけることを願っています.
ありがとう
これは、以前の質問のより高度な続編です。
これは、物事を少し明確にするための SQLFiddle へのリンクです
(場所ごとに) 次のようなものを返す必要があります。
1 階
---------------
ガレージ
- ラジエーター
キッチン
- 炊飯器
- 冷蔵庫
これよりもさらに多くのレベルがありますが、始めることができれば、必要に応じてさらに進んでいけることを願っています.
ありがとう
このソリューションを使用して、既知の深さの階層構造を表示できます。
SELECT a.name
FROM
(
SELECT
CONCAT('- - - - - - - - - -> ', a.asset_name) AS name,
CONCAT(c.location_key, c.location_name, b.sub_location_name, a.asset_name) AS orderfactor
FROM asset a
INNER JOIN sub_location b ON a.sub_location_key = b.sub_location_key
INNER JOIN location c ON b.location_key = c.location_key
UNION ALL
SELECT
CONCAT('- - - - -> ', a.sub_location_name),
CONCAT(b.location_key, b.location_name, a.sub_location_name)
FROM sub_location a
INNER JOIN location b ON a.location_key = b.location_key
UNION ALL
SELECT
location_name,
CONCAT(location_key, location_name)
FROM location
) a
ORDER BY a.orderfactor
より多くのレベルについては、副選択にさらにユニオンを追加できます。
結果セットの例:
Ground Floor
-----> Garage
----------> Radiator
-----> Kitchen
----------> Cooker
----------> Fridge
First Floor
-----> Bedroom
----------> Radiator
----------> Taps
Second Floor
-----> Bathroom
----------> Shower
----------> Taps
----------> Toilet
Third Floor
上記でフォーマットしたようにSQLはネストされたレコードを返すことができないため、行をフロア、次にsub_locationで並べ替えるクエリを返すだけで済みます。行ごとにlocation
とが繰り返されますが、結果を印刷するときのアプリケーションコードループでは、上記のようにフォーマットします。sub_location
SELECT
location.location_name,
sublocation.sub_location_name,
asset.asset_name
FROM
location
LEFT JOIN sub_location ON location.location_key = sublocation.location_key
LEFT JOIN assets ON sub_location.sub_location_key = assets.sub_location_key
ORDER BY
location.location_name,
sub_location.sub_location_name
アプリケーションで行セットをループするときは、新しい場所またはsub_locationが変更されたときにのみ印刷します。フォーマットはコードで行われます。
行がすべて配列内にあると仮定します$rowset
。
// Store location, sub_location for each loop
$current_loc = "";
$current_subloca = "";
foreach ($rowset as $row) {
// If the location changed, print it
if ($row['location'] != $current_loc) {
echo $row['location_name'] . "\n";
// Store the new one
$current_loc = $row['location_name'];
}
// If the sub_location changed, print it
if ($row['sub_location'] != $current_subloc) {
echo $row['sub_location_name'] . "\n";
$current_subloc = $row['sub_location_name'];
}
echo $row['asset_name'] . "\n";
}
MySQL5なら
SELECT L.location_name, GROUP_CONCAT(DISTINCT S.sub_location_name), GROUP_CONCAT(A.asset_name)
FROM location L
INNER JOIN sub_location S ON L.location_key = S.location_key
INNER JOIN asset A ON A.sub_location_key = S.sub_location_key
GROUP BY S.sub_location_name ORDER BY L.location_key