【问题标题】:Querying Comma Separated Values Grouped by Column查询按列分组的逗号分隔值
【发布时间】:2013-10-26 12:33:23
【问题描述】:

我有一个名为“学生”的表格,其中包含以下列:学生姓名、大学和技能。 Student Name 是 varchar 类型,Skills 以 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。 但这会导致很多重复。

我在 select 中使用了 IIF 语句来获取列 Skills Columns 并且每一行都是一个学生。但我希望每一行都是学院而不是学生。

【问题讨论】:

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


    【解决方案1】:

    基于您对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
    

    注意:如您所见,使用当前形式的数据将继续使您的生活变得比实际需要的更难。也许您会将此视为又一个strong提示您应该修复您的数据模型!

    【讨论】:

    • 太棒了!非常感谢!另外,如果我需要将它们分组为 College 和 Gender,那么只需添加 GROUP BY COllege,Gender 似乎不起作用。 ACCESS 向我询问 Gender 参数值?这是怎么回事?
    • 嘿,我已将您的答案标记为正确,但对问题进行了一些编辑,以包括男性/女性列。请看一看。谢谢!
    • @SLearner 您已更新问题文本,但我在您的示例数据中看不到任何“M”或“F”值。尽管如此,您应该尝试使用现有答案中已经介绍的技术将男性/女性计数整合到结果中,然后如果您有一个特定问题,那么您应该为它创建一个新问题. (当人们提出问题,得到答案,然后不断对问题进行实质性更改时,这会变得非常乏味。有点像“功能蠕变”......)
    【解决方案2】:

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

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

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

    【讨论】:

    • 是的,我读过它。可悲的是,我现在无能为力来改变表结构。但是,@GordThompson 为我的问题提供了正确的解决方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多