SQL可以从"列表"中进行SELECT吗?里面的例子

mei*_*ryo 3 mysql sql pivot

我的表格如下

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     |
Run Code Online (Sandbox Code Playgroud)

所以我希望输出如下:

| 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    |         |      |         |      |
Run Code Online (Sandbox Code Playgroud)

我将使用什么类型的连接或联合语句?每个人最多只有5个技能.

那么SQL的外观怎么样?它甚至可能吗?

我完全迷失了,不知道从哪里开始.

Joh*_*Woo 5

由于您已经提到过a Name可以有最大值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
Run Code Online (Sandbox Code Playgroud)

OUTPUT

??????????????????????????????????????????????????????????
? NAME ? SKILL_1 ? SKILL_2 ? SKILL_3 ? SKILL_4 ? SKILL_5 ?
??????????????????????????????????????????????????????????
? jon  ? C++     ? CSS     ? HTML    ? Java    ? JS      ?
? mary ? Perl    ? PHP     ? Ruby    ? (null)  ? (null)  ?
??????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

简要说明

我们把它分解吧.查询中有两个部分.

查询的第一部分(第1部分)Skill为每个部分生成数字序列Name.它只是使用相关子查询来模拟一个窗口函数ROW_NUMBER,其MySQL不支持.

第二部分,第2部分,根据第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
Run Code Online (Sandbox Code Playgroud)

OUTPUT

????????????????????????????????????????????????????????????????????????????????????????????????????????????
? 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)  ?
????????????????????????????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)