関連するクライアントのルックアップですべてタグ付けされたプロジェクトのテーブルがあり、次のようなデータを表示したい:
- クライアント 1
- プロジェクト1
- プロジェクト 2
- プロジェクト 3
- クライアント 2
- プロジェクト1
- プロジェクト 2
- クライアント 3
- プロジェクト1
- プロジェクト 2
- プロジェクト 3
そうすれば、テーブルからプロジェクトを取り戻し、クライアントごとに「グループ化」できます。この行為を何と呼びますか?ネストされたグループですか、それともそのようなものですか?
関連するクライアントのルックアップですべてタグ付けされたプロジェクトのテーブルがあり、次のようなデータを表示したい:
そうすれば、テーブルからプロジェクトを取り戻し、クライアントごとに「グループ化」できます。この行為を何と呼びますか?ネストされたグループですか、それともそのようなものですか?
レイアウトしたように、SQLクエリはネストされた結果を提供できません1。代わりに、結果セットはフラットで、Client
プロジェクトごとに 1 回、複数回繰り返す必要があります。本当にあなたのSQLクエリでは、同様のClient
値を一緒にソートするのは順序の問題です:ORDER BY client
Client 1 Project 1
Client 1 Project 2
Client 1 Project 3
Client 2 Project 1
Client 2 Project 2
Client 2 Project 3
アプリケーションの表示ロジックではClient
、値が前の値から変更されたときにのみ新しい値を出力します。
# Start with empty last_client
last_client = ""
loop_over_rows
if last_client is not equal to current_row->client
print new row->client
# Print all projects
print row->project
# Store the current client to compare on next loop
last_client = row->client
endloop
1これは SQL で多くのクレイジーな文字列操作と を使用して実行できますUNION
が、これはプレゼンテーションの問題であり、実際には SQL ではなくアプリケーションのプレゼンテーション ロジックに属します。
タグで指定されていないRDBMSが再帰SQLをサポートしている場合は、実行しようとしているレイアウトを概算できます。
次のSQLは、Teradataのデータディクショナリテーブルに対して機能します。階層列は、所有権チェーン内のデータベースの深さに基づいてオフセットされます。そこから、あなたはその概念を取り入れてあなたの状況にそれを適用することができるはずです。
WITH RECURSIVE cte (DatabaseName, Path, Parent, Level) AS
(
SELECT TRIM(DatabaseName)
,DatabaseName(VARCHAR(600))
,TRIM(DatabaseName)
,0 (BYTEINT)
FROM DBC.Databases d
WHERE DatabaseName = 'DBC'
UNION ALL
SELECT TRIM(d.DatabaseName)
,cte.Path || '.' || TRIM(d.DatabaseName)
,cte.Path
,Level + 1
FROM DBC.Databases d
,cte
WHERE d.OwnerName = cte.DatabaseName
AND d.DatabaseName <> d.OwnerName
AND Level < 20
)
SELECT Level
, SUBSTRING(CAST('' AS CHAR(60)) FROM 1 FOR Level * 2) || DatabaseName AS Hierarchy
, Path
, Parent
FROM cte
ORDER BY Path;