这是第一次-我正在尝试做这样的事情-所以请多多包涵。
这是在MySql上。
我正在尝试生成一份报告,以查看哪些学生完成了哪些主题以及在什么日期完成。
这是我运行的当前查询
选择u.email,t.topic_name,tu.date_created为“完成日期”
来自topic_user tu
加入主题t ON tu.topic_id = t.topic_id
加入用户u ON tu.user_id = u.user_id
这将返回结果,例如
电邮| topic_name |完成日期
[email protected] | ABC | 2012/03/01
[email protected] | DEF | 2012/03/02
[email protected] | ABC | 2012/03/08
[email protected] | GHI | 2012/03/08
[email protected] | ABC | 2012/03/02
[email protected] | XYZ | 2012/03/10
我要生成报告的方式是将主题名称作为列标题,并将其完成日期作为值
电邮| ABC | DEF | GHI | JKL | XYZ
[email protected] | 2012年3月8日| 2012年3月2日| 2012年3月8日|空|空值
[email protected] | 2012年3月2日|空|空|空| 2012/03/10
要注意的几件事是:
1)所有主题名称都将来自主题表-即使尚未由学生完成,该值也应显示为null
2)如果是学生[email protected]他已经研究了ABC主题两次-但报告应获得最新日期。
我想我必须编写一个存储过程来完成此任务。就像首先从主题表中提取所有主题名称,然后创建一个临时视图并填充它一样。
我会很感激您能提供的任何帮助。
非常感谢
最佳答案
我尚未对此进行测试,并且我在MySQL方面的经验有限,但我希望以下是您的追求。它使用SELECT
函数动态创建GROUP_CONCAT
语句,然后执行它(这是我不确定在MySQL中执行它的方式)。
SET @SQL = (
SELECT CONCAT('SELECT Email,', GROUP_CONCAT(SelectText), ' FROM Topic_User tu INNER JOIN Users u ON u.User_ID = tu.User_ID GROUP BY Email')
FROM ( SELECT CONCAT(' MAX(CASE WHEN Topic_ID = ', Topic_ID, ' THEN tu.Date_Created END) AS `', Topic_Name, '`') AS SelectText
FROM Topic
) AS d);
PREPARE stmt FROM @SQL;
EXECUTE stmt
当然,如果您的主题变化不是很规律,则可以使用:
SELECT Email,
MAX(CASE WHEN Topic_ID = 1 THEN tu.Date_Created END) AS ABC,
MAX(CASE WHEN Topic_ID = 2 THEN tu.Date_Created END) AS DEF,
MAX(CASE WHEN Topic_ID = 3 THEN tu.Date_Created END) AS GHI,
MAX(CASE WHEN Topic_ID = 4 THEN tu.Date_Created END) AS JKL,
MAX(CASE WHEN Topic_ID = 5 THEN tu.Date_Created END) AS XYZ
FROM Topic_User tu
INNER JOIN users u
ON u.User_ID = tu.User_ID
GROUP BY Email
并在每次添加新主题时更改查询(这是上述过程产生的查询)。
关于mysql - MySql-通过将行转换为列来生成报告的Sql查询或过程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9669384/