1

シナリオは単純です。Aテーブル、Bテーブル、C1テーブル、C2テーブルの4つのテーブルがあります。Aはルートレベルのテーブルであり、BはAを参照し、C1とC2はBを参照します。ただし、各B.IDは、C1またはC2のいずれかでのみ参照でき、両方で参照することはできません。結果は.CSVファイルにエクスポートされ、さまざまな目的で使用されます。ここでの質問は、外部ソフトウェアでの情報の管理を容易にするだけでなく、読みやすさにも関係しています。

4つのテーブルすべてのすべてのデータを返し、関係をそのままにして、A、B、C1、C2の順に並べるクエリを作成しました。

SELECT A.*, B.*, C1.*, C2.*
FROM A
JOIN B 
LEFT JOIN C1
LEFT JOIN C2
ORDER BY A.ID, B.ID, etc.

そしてこれを手に入れました:

A.ID | B.ID | C1.ID | C2.ID
    1|     1|      1|  NULL
    1|     1|      2|  NULL
    1|     2|      1|  NULL
    1|     2|      2|  NULL
    1|     2|      3|  NULL
    2|     1|   NULL|     1
    2|     1|   NULL|     2
....

ここでの質問は次のとおりです。結果セットが冗長データで詰まらないように、結合ごとに最初の個別の行のみを返すにはどうすればよいですか。基本的に、上記の結果は次のようになります。

A.ID | B.ID | C1.ID | C2.ID
    1|     1|      1|  NULL
     |      |      2|  NULL
     |     2|      1|  NULL
     |      |      2|  NULL
     |      |      3|  NULL
    2|     1|   NULL|     1
     |      |   NULL|     2
....

おそらく、各結合をサブクエリにして結果をランクで分割するか、一時テーブルを作成して必要なロジックで結果をスラムすることでこれを行うことができますが、これはコンソールアプリで使用されるため、ソリューションを可能な限りクリーンでシンプルかつ最適化してください。

何か案は?

4

1 に答える 1

4

これはデータではなくレポート/フォーマットであるため、SQL ではなくアプリケーションで処理する必要があります。

つまり、これにより、要件に近いものが生成されます

select 
    case arn when 1 then convert(varchar(10),aid) else '' end as aid,
    case brn when 1 then convert(varchar(10),bid) else '' end as bid,
    case crn when 1 then convert(varchar(10),c1id) else '' end as c1id,
    c2id        
from
(    
           select a.id aid, b.id bid, c1.id c1id, c2.id c2id,
    ROW_NUMBER() over(partition by a.id order by a.id,b.id,c1.id,c2.id) arn,
    ROW_NUMBER() over(partition by a.id,b.id order by a.id,b.id,c1.id,c2.id) brn,
    ROW_NUMBER() over(partition by a.id,b.id,c1.id order by a.id,b.id,c1.id,c2.id) crn
           FROM A 
           JOIN B  
           LEFT JOIN C1 
           LEFT JOIN C2 

) v
于 2012-09-07T10:27:09.500 に答える