查询由列分组的逗号分隔值

时间:2013-10-17 20:24:36

标签: sql ms-access ms-access-2010

我有一个叫做学生名单的表:学生姓名,大学和技能。 学生姓名为varchar类型,技能包含CSV格式学生的技能。此外,性别列有'M'或'F' 例如:

College Skills                  Student Name
ABC     C,Python,Python,JAVA    S1
ABC     C,Python,JAVA,CSS       S2
ABC     C,Python,JAVA,JS,C#     S3
ABC     C,Python,JAVA           S4
XYZ     C,Python,C#             S5
XYZ     C,Python,C#             S6
XYZ     C,Python,C#             S7
UT      C,SQL,JS,CSS            S8

我想显示一个像这样的表

College   Men Women  C     C++     C#      Python      JAVA      SQL        JS        CSS
ABC       2     2    4     0       1         4         4        0            1         1
XYZ       1     2    3     0       3         3         0        0            0         0
UT        1     0    1     0       0         0         0        1            1         1

我该怎么做?

我做了一个查询,显示拥有SKILLS为1或0的所有学生。 但这导致了很多重复。

我在选择中使用了IIF语句获取列技能列,每行都是学生。但我希望每一行都是学院而不是学生。

2 个答案:

答案 0 :(得分:2)

previous question的答案为基础,修订后的查询

SELECT
    [Student Name],
    College,
    IIf(Skillz LIKE "*,C,*",1,0) AS _C,
    IIf(Skillz LIKE "*,Python,*",1,0) AS _Python,
    IIf(Skillz LIKE "*,JAVA,*",1,0) AS _JAVA,
    IIf(Skillz LIKE "*,CSS,*",1,0) AS _CSS,
    IIf(Skillz LIKE "*,JS,*",1,0) AS _JS,
    IIf(Skillz LIKE "*,C#,*",1,0) AS _CSharp,
    IIf(Skillz LIKE "*,SQL,*",1,0) AS _SQL
FROM
    (
        SELECT 
            [Student Name],
            College,
            "," & Skills & "," AS Skillz
        FROM Students
    )

返回

Student Name  College  _C  _Python  _JAVA  _CSS  _JS  _CSharp  _SQL
------------  -------  --  -------  -----  ----  ---  -------  ----
S1            ABC       1        1      1     0    0        0     0
S2            ABC       1        1      1     1    0        0     0
S3            ABC       1        1      1     0    1        0     0
S4            ABC       1        1      1     0    0        0     0
S5            XYZ       1        1      0     0    0        0     0
S6            XYZ       1        1      0     0    0        0     0
S7            XYZ       1        1      0     0    0        0     0
S8            UT        1        0      0     1    1        0     1

所以,现在我们需要做的就是添加一个外部查询来添加值

SELECT 
    College, 
    SUM([_C]) AS C,
    SUM([_Python]) AS Python,
    SUM([_JAVA]) AS JAVA,
    SUM([_CSS]) AS CSS,
    SUM([_JS]) AS JS,
    SUM([_CSharp]) AS CSharp,
    SUM([_SQL]) AS SQL
FROM
    (
        SELECT
            [Student Name],
            College,
            IIf(Skillz LIKE "*,C,*",1,0) AS _C,
            IIf(Skillz LIKE "*,Python,*",1,0) AS _Python,
            IIf(Skillz LIKE "*,JAVA,*",1,0) AS _JAVA,
            IIf(Skillz LIKE "*,CSS,*",1,0) AS _CSS,
            IIf(Skillz LIKE "*,JS,*",1,0) AS _JS,
            IIf(Skillz LIKE "*,C#,*",1,0) AS _CSharp,
            IIf(Skillz LIKE "*,SQL,*",1,0) AS _SQL
        FROM
            (
                SELECT 
                    [Student Name],
                    College,
                    "," & Skills & "," AS Skillz
                FROM Students
            )
    )
GROUP BY College

...返回:

College  C  Python  JAVA  CSS  JS  CSharp  SQL
-------  -  ------  ----  ---  --  ------  ---
ABC      4       4     4    1   1       0    0
UT       1       0     0    1   1       0    1
XYZ      3       3     0    0   0       0    0

注意:正如您所看到的,使用当前形式的数据将继续使您的生活更加艰难。也许您会将此作为另一个强大提示, 修复您的数据模型!

答案 1 :(得分:0)

在单个字段中存储逗号分隔值绝不是一个好主意。这有时称为SQL反模式。您正在使用关系数据库,因此请将其设为关系数据库。

创建一个名为Skills的单独表格,并在其中放置一个与您的studentId字段匹配的外键字段。

对于最终结果,要获得您想要的视图,我认为您需要使用交叉表查询。