3

個人のすべての電話、電子メール、および組織を取得して、フラット ファイル形式で表示しようとしています。行数は n である必要があります。ここで、n は組織、電子メール、または電話の最大数です。すべての値が行に表示されると、NULL 値が表示され、NULL が最後の値になります。電子メールと電話は、1 人につき 1 つの PreferredInd のみを持つことができます。これらを同じ行に配置したい (そのうちの 1 つは NULL にすることができます)。より複雑なクエリでこれを実行しようとしましたが、うまくいかなかったため、この単純な例を使用してやり直しました。

テーブルと値の例:

@ContactPerson
Id        Name
1        John Doe

@ContactEmail
Id   PersonId     Email            PreferredInd
1    1            johndoe@us.gov     0
2    1            jdoe@us.gov        1
3    1            johndoe@gmail.com  0

@ContactPhone
Id   PersonId     Phone            PreferredInd
1    1            888-867-5309       0
2    1            305-476-5234       1

@ContactOrganization
Id   PersonId     Organization
1    1            US Government
2    1            US Army

結果のセットを次のようにしたい:

Name           Organization    PreferredInd  Email             Phone
John Doe       US Government   1            jdoe@us.gov        888-867-5309
John Doe       US Army         0            johndoe@us.gov     305-467-5234
John Doe       NULL            0            johndoe@gmail.com  NULL



この例の完全な SQL コードは、pastebin にあります。また、サンプル テーブルを作成するためのコードも含まれています。電子メールの数が組織または電話の数を超える場合に機能しますが、常にそうであるとは限りません。探している結果を取得する方法がわかりません。私が扱っている実際のテーブルには、1 人あたりのメール、電話、または組織が 0 または無限にある可能性があります。さらに多くの値もありますが、自分で修正できます。

クエリの修正を手伝ってもらえますか、それとももっと簡単な方法を教えてもらえますか? ご不明な点がございましたら、お気軽にお問い合わせください。お答えできるよう努めます。

4

2 に答える 2

4

このようなもの?

with cte_e as (
    select
        *,
        row_number() over(order by PreferredInd desc, Id) as rn
    from ContactEmail
), cte_p as (
    select
        *,
        row_number() over(order by PreferredInd desc, Id) as rn
    from ContactPhone
), cte_o as (
    select
        *,
        row_number() over(order by Organization) as rn
    from ContactOrganization
), cte_d as (
    select distinct rn, PersonId from cte_e union
    select distinct rn, PersonId from cte_p union
    select distinct rn, PersonId from cte_o
)
select
    pr.Name, o.Organization, e.Email, p.Phone
from cte_d as d
    left outer join ContactPerson as pr on pr.Id = d.PersonId
    left outer join cte_e as e on e.PersonId = d.PersonId and e.rn = d.rn
    left outer join cte_p as p on p.PersonId = d.PersonId and p.rn = d.rn
    left outer join cte_o as o on o.PersonId = d.PersonId and o.rn = d.rn

sql fiddle demo

少し不器用です。これを行うには他にもいくつかの方法が考えられますが、これが最も読みやすいと思います

于 2013-10-02T19:20:48.897 に答える
0

ステップ1

すべてのテーブルの完全な結合を行うクエリを作成します。これにより、各人 (各電子メールまたは電話番号) に対して多くの重複行が発生します。

ステップ 2 GroupBy を使用して行をグループ化し、Case または Decode キーワード(ac# switch ステートメントなど)を使用して優先行値を検索し、表示する値として選択する 2 番目のクエリを記述します。

于 2013-10-02T19:14:54.660 に答える