2016-06-23 4 views
0

私はすでに尋ねたこの質問に少し似て質問があります:Mysql, reshape data from long/tall to wideSQL:ワイド表に狭い表を変換し

私の複雑さは、私のデータ構造は、揮発ことができるという事実が付属して、変更の対象となりますユーザーの裁量でだから、私の列は、テーブルを移入するフィールドに応じて、集計(拡大または縮小)を変更することができます。

INPUT:ここで私のテーブルにあるかもしれないものの例

は、いくつかのレコードがある

LOCATION  User_Name  Title  Phone 
Living Room  Joe Schmo  Worker  12-23 
Baseball Park Jane Doe   Worker  23-34 
Backyard  Tiger Woods  Worker  34-45 

そこ変動のかなり良い量は、タイトルにあります、そして多分、おそらく中場所

INPUT:だから私は何をする必要があるか

LOCATION  User_Name  Title  Phone 
Living Room  Batman   Manager  9112 
Baseball Park Batman   Manager  9112 
Backyard  Batman   Manager  9112 

、マッチした場所に、私は場所に関連付けられているすべてのユーザとの広いテーブルを持っている必要があります:

OUTPUT:

LOCATION  User_Name Title Phone User_Name Title  Phone 
Living Room  Joe Schmo Worker 12-23 Batman  Manager 9112 
Baseball Park Jane Doe  Worker 23-34 Batman  Manager 9112 
Backyard  Tiger Woods Worker 34-45 Batman  Manager 9112 

任意の提案のヒントが高く評価されるだろう。私はこの例を再現しようとしましたが、明らかに、テーブルが動的に拡大または縮小できるという事実をどのように説明していますか?私はピボットをしようとしましたが、複数のフィールドで動作するようにはできませんでした。

思考?

+1

考えていることを再考してください - あなたのテーブルは現在正常に**正常化されています。あなたが望むのはテーブルを非正規化することです。あなたが簡単な答えを得たいのであれば、「すべてのユーザーにタイル=「マネージャ」を与えてください。現在は非常に簡単です。 'SELECT * FROM table WHERE title = 'Manager'' - 単純に、非常に効率的です。インデックスが' Title'カラムにある場合。非正規化の後では、次のようにする必要があります: 'SELECT * FROM table WHERE title1 = 'Manager' OR title2 = 'Manager' OR ...... Ttile2876 = 'Manager''。クエリは扱いにくく、スピードは貧弱です。私はhigallyこの考えをabondonにお勧めします。 – krokodilko

+0

ああ、私を信じて、これをやろうとするのは、釘のようなものです。残念ながら、プレゼンテーションのためにこのテーブルを非正規化する必要があります。そのプレゼンテーションには私のためにそれを非正規化する抽象レイヤはありません。その代わりに、要件は、実行するためにデータベース・レベルに引き渡されます。 TLDR;私はこれを放棄したいと思いますが、私は単純にできません。 – Stunna

+0

私はこの会話に追加すると思います。私はもともとこのテーブルを設計するのは、維持するのが比較的簡単なテーブルになると思っていました。ユーザーがデータテーブルの作成を開始した後、この複雑な結合を必要とする表の使用が突然変更されましたか?ピボット?ソフトウェア要件のために。私は、このテーブルを事前定義された、切り詰められていない、COTS製品に加工するという彼らの要求を唱えようとしています。 – Stunna

答えて

1

PIVOTクエリを使用して行うことができます。
結果の幅はどれくらいであるかを事前に決めておく必要があります。つまり、最終結果に含める必要がある列(名前、タイトル、電話番号)の数のグループを意味します。たとえば、以下の

が列(名前+タイトル+電話)の3グループに分け、表全体を分割:

WITH my_data AS (
    SELECT LOCATION, User_Name, Title, Phone, 
      trunc(rn/3) as group_number, 
      rn - 3 * trunc(rn/3) as rownum_within_group 
    FROM (
     SELECT t.* , 
       row_number() over (partition by location order by user_name) - 1 As rn 
     FROM table1 t 
    ) t 
    -- ORDER BY Location, user_name 
) 
SELECT * 
FROM my_data 
PIVOT (
    MAX(User_name) As user_name, 
    MAX(Title) as Title, 
    MAX(Phone) As Phone 
    FOR rownum_within_group IN (0 as G0,1 As G1 ,2 As G2) 
) 
ORDER BY 1,2; 

とあなたの例から、わずかに変更されたデータのためのサンプルの結果(私は追加の「Batman2」を追加しました+「Batman3」+「Batman4」エントリ)である:そこ場所Living Room 5人のユーザーがあるので、この位置は、結果セットに2列に分割され

LOCATION  GROUP_NUMBER G0_USER_NAME G0_TITLE G0_PHONE G1_USER_NAME G1_TITLE G1_PHONE G2_USER_NAME G2_TITLE G2_PHONE 
Backyard     0 Batman   Manager  9112  Tiger Woods  Worker  34-45   
Baseball Park   0 Batman   Manager  9112  Jane Doe  Worker  23-34   
Living Room    0 Batman   Manager  9112  Batman2   Manager  9112  Batman3   Manager  9112 
Living Room    1 Batman4   Manager  9112  Joe Schmo  Worker  12-23 

、最初の行は、3人のユーザ、及び第二を有します行には2人のユーザーがいます(上記の例では最後の2行を参照)。

+0

これは間違いなく機能しています。どのようにしてこのようにすばやく動くのか驚いています。私が不思議に思っていたことの1つは、有限数の列やグループを持たない方法でした。しかし、ピボットテーブルで必要な集約関数が必要なため、回避する方法はないと思いますか? – Stunna

関連する問題