【问题标题】:Dynamic Pivot Table MySql动态数据透视表 MySql
【发布时间】:2014-07-11 19:01:31
【问题描述】:

我在数据库中有一个表格,记录学生的分数,如下所示:

| id     | criteriaid   |  mark     | studentid     |
| 1      | 5            |  62       | 5             |
| 2      | 6            |  54       | 5             |
| 3      | 7            |  48       | 5             |

然后链接到一个标准表,如下所示:

| id     | title        |
| 5      | Presentation |
| 6      | Communication|
| 7      | Research     |

还有一个像这样的学生表:

| id     |firstname     | lastname       |
| 10     |Joe           | Bloggs         |

虽然我将表格连接在一起没有问题,但可能看起来像这样:

| id | firstname | lastname  |  criteria     | mark     |
| 10 | Joe       | Bloggs    |  Presentation | 62       |
| 10 | Joe       | Bloggs    |  Communication| 54       |
| 10 | Joe       | Bloggs    |  Research     | 48       |

我一直在尝试使用数据透视表教程,但无法获得我想要的结果。我认为这是一个动态数据透视表。 (标准需要是动态的)。这就是我想要的:

| id | firstname | lastname  |  Presentation | Communication | Research  |
| 10 | Joe       | Bloggs    |       62      |      54       |     48    |

目前我正在尝试按照此处trouble with mysql pivot table的建议进行硬编码

SELECT s.firstname, s.lastname, m.mark,
  max(case when c.title = 'Attitude' then m.mark end) attitude,
  max(case when c.title = 'Acting' then m.mark end) acting,
  max(case when c.title = 'Presentation' then m.mark end) presentation,
  max(case when c.title = 'Voice' then m.mark end) voice
from marks m
LEFT JOIN criteria c ON m.criteriaid = c.id
LEFT JOIN students s ON s.id = m.studentid

现在运行良好,但我正在寻求动态解决方案。我会继续努力 - 如果有人能提供帮助,我们将不胜感激。

我已经到了这里

    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'max(case when c.title = ''',
          title,
          ''' then m.mark end) AS ',
          replace(title, ' ', '')
        )
      ) INTO @sql
    from criteria;

    SET @sql = CONCAT('SELECT s.firstname, s.lastname,
    ', @sql,'
    from marks m
    LEFT JOIN criteria c ON m.criteriaid = c.id
    LEFT JOIN students s ON s.id = m.studentid
    group by s.id;');

    PREPARE stmt FROM @sql;
    EXECUTE stmt;

    DEALLOCATE PREPARE stmt;

这可能有效,但在 PHPMyAdmin 中不起作用...正在寻找解决方案!

【问题讨论】:

  • 请向我们展示一些您迄今为止尝试过的示例。否则,您似乎希望有人在这里完成您的工作/家庭作业。并且不确定您所说的“动态”是什么意思 - 查询会针对当前数据运行,无论是在 MySQL 中本机还是通过 PHP 或其他调用应用程序。祝你好运。
  • 我看到你已经用 PHP 标记了这个。虽然你可以在 MySQL 中编写一个 sproc 来动态组装一些准备好的语句,但返回有序数组并在应用程序级别处理显示逻辑(例如简单的 PHP 循环)更简单
  • 在 SQL 查询上做这件事不是一个好主意......最好在代码上做。如果你需要它是动态的......
  • 我的回答和你的基本一样。 FROM MARKS 子句之前有一个不需要的逗号
  • 谢谢,是的,我刚刚发现了这个,它已经开始工作了。

标签: php mysql sql pivot


【解决方案1】:

很难看出如何创建一个 sql 表,该表将根据表中的数据具有不同的列,但您可以获得一些您想要的。

您可以使用如下查询:

SELECT studentid,
   MAX(CASE WHEN criteriaid=5 THEN mark END) AS Presentation,
   MAX(CASE WHEN criteriaid=6 THEN mark END) AS Communication,
   MAX(CASE WHEN criteriaid=7 THEN mark END) AS Research
FROM marks
GROUP BY studentid

这并不能回答您的问题 - 但它在 SQL 中而不是在 php 中完成大部分工作。您也许可以根据表中的条件在 PHP 中构造 SQL 语句。

【讨论】:

  • 谢谢,是的,这与我想要实现的目标相似
【解决方案2】:

这是工作结果,但在 PHP 中不起作用。已决定使用硬编码选项和 PHP 来构建 SQL 字符串。

SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'max(case when c.title = ''',
          title,
          ''' then m.mark end) AS ',
          replace(title, ' ', '')
        )
      ) INTO @sql
    from criteria;

    SET @sql = CONCAT('SELECT s.firstname, s.lastname,
    ', @sql,'
    from marks m
    LEFT JOIN criteria c ON m.criteriaid = c.id
    LEFT JOIN students s ON s.id = m.studentid
    group by s.id;');

    PREPARE stmt FROM @sql;
    EXECUTE stmt;

    DEALLOCATE PREPARE stmt;

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多