3

次のように私のテーブル

name
| id | name |
|  1 | jon  |
|  2 | mary |

skill
| id | skill | level |
|  1 | C++   | 3     |
|  1 | Java  | 2     |
|  1 | HTML  | 5     |
|  1 | CSS   | 4     |
|  1 | JS    | 5     |
|  2 | PHP   | 4     |
|  2 | Ruby  | 3     |
|  2 | Perl  | 1     |

だから私は出力を次のようにしたい:

| name | skill_1 | lv_1 | skill_2 | lv_2 | skill_3 | lv_3 | skill_4 | lv_4 | skill_5 | lv_5 |
| jon  | C++     | 3    | Java    | 2    | HTML    | 5    | CSS     | 4    | JS      | 5    |
| mary | PHP     | 4    | Ruby    | 3    | Perl    | 1    |         |      |         |      |

どのタイプの join または union ステートメントを使用しますか? 1 人につき最大 5 つのスキルしかありません。

では、このための SQL はどのようになりますか? それは可能ですか?

私は完全に道に迷っており、どこから始めればよいかわかりません。

4

4 に答える 4

5

Namea の最大値は であると述べたので5 Skills、この問題は静的クエリを使用して実行できます。

-- <<== PART 2
SELECT  Name,
        MAX(CASE WHEN RowNumber = 1 THEN Skill END) Skill_1,
        MAX(CASE WHEN RowNumber = 2 THEN Skill END) Skill_2,
        MAX(CASE WHEN RowNumber = 3 THEN Skill END) Skill_3,
        MAX(CASE WHEN RowNumber = 4 THEN Skill END) Skill_4,
        MAX(CASE WHEN RowNumber = 5 THEN Skill END) Skill_5
FROM
        ( -- <<== PART 1
            SELECT  a.Name, 
                    b.Skill,
                    (
                        SELECT  COUNT(*)
                        FROM    Skill c
                        WHERE   c.id = b.id AND
                                c.Skill <= b.Skill) AS RowNumber
            FROM    Name a
                    INNER JOIN Skill b
                        ON a.id = b.id
        ) x
GROUP   BY Name

出力

╔══════╦═════════╦═════════╦═════════╦═════════╦═════════╗
║ NAME ║ SKILL_1 ║ SKILL_2 ║ SKILL_3 ║ SKILL_4 ║ SKILL_5 ║
╠══════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ jon  ║ C++     ║ CSS     ║ HTML    ║ Java    ║ JS      ║
║ mary ║ Perl    ║ PHP     ║ Ruby    ║ (null)  ║ (null)  ║
╚══════╩═════════╩═════════╩═════════╩═════════╩═════════╝

簡単な説明

分解してみましょう。クエリには 2 つの部分があります。

クエリの最初の部分であるPART 1Skillは、 for everyの一連の数値を生成しますName。サポートされていないウィンドウ関数ROW_NUMBERを模倣するために、相関サブクエリを使用するだけです。MySQL

2 番目の部分であるPART 2は、 PART 1で生成された連続番号に基づいて、行を列に転置します。CASE数値の値をテストするために使用し、数値にSkill関連付けられているを返します。数値が一致しない場合はNULL値を返します。Name次に、使用するすべてのグループの列を集計するMAX()ため、存在する場合SKILLの代わりに返されNULLます。

更新 1

SELECT  Name,
        MAX(CASE WHEN RowNumber = 1 THEN Skill END) Skill_1,
        MAX(CASE WHEN RowNumber = 1 THEN Level END) Level_1,
        MAX(CASE WHEN RowNumber = 2 THEN Skill END) Skill_2,
        MAX(CASE WHEN RowNumber = 2 THEN Level END) Level_2,
        MAX(CASE WHEN RowNumber = 3 THEN Skill END) Skill_3,
        MAX(CASE WHEN RowNumber = 3 THEN Level END) Level_3,
        MAX(CASE WHEN RowNumber = 4 THEN Skill END) Skill_4,
        MAX(CASE WHEN RowNumber = 4 THEN Level END) Level_4,
        MAX(CASE WHEN RowNumber = 5 THEN Skill END) Skill_5,
        MAX(CASE WHEN RowNumber = 5 THEN Level END) Level_5
FROM
        (
            SELECT  a.Name, 
                    b.Skill,
                    (
                        SELECT  COUNT(*)
                        FROM    Skill c
                        WHERE   c.id = b.id AND
                                c.skill <= b.skill) AS RowNumber,
                    b.Level
            FROM    Name a
                    INNER JOIN Skill b
                        ON a.id = b.id
        ) x
GROUP   BY Name

出力

╔══════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╗
║ NAME ║ SKILL_1 ║ LEVEL_1 ║ SKILL_2 ║ LEVEL_2 ║ SKILL_3 ║ LEVEL_3 ║ SKILL_4 ║ LEVEL_4 ║ SKILL_5 ║ LEVEL_5 ║
╠══════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ jon  ║ C++     ║       3 ║ CSS     ║       4 ║ HTML    ║       5 ║ Java    ║ 2       ║ JS      ║ 5       ║
║ mary ║ Perl    ║       1 ║ PHP     ║       4 ║ Ruby    ║       3 ║ (null)  ║ (null)  ║ (null)  ║ (null)  ║
╚══════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╝
于 2013-06-02T07:44:10.010 に答える