我从MySQL数据库中获取以下数据:
+------------+------------+----------------+
| competency | totalscore | date_evaluated |
+------------+------------+----------------+
| A | 0 | null |
| B | 0 | null |
| C | 0 | null |
| D | 0 | null |
| E | 5 | 2018-03-01 |
| F | 4 | 2018-03-01 |
| E | 4 | 2018-03-02 |
| F | 3 | 2018-03-02 |
+------------------------------------------+
哪个是从两个单独的表中检索的
+-----------------+
| competencies |
+-----------------+
| competency_ID |
| competency |
+-----------------+
+-----------------+
| scoring_self |
+-----------------+
| student_ID |
| competency_ID |
| score |
| date_evaluated |
+-----------------+
我想以下列形式显示在.aspx页面上:
+----------------+-------+-------+-------+-------+-------+--------+
| Date Evaluated | A | B | C | D | E | F |
+----------------+-------+-------+-------+-------+-------+--------+
| 2018-03-01 | 0 | 0 | 0 | 0 | 5 | 4 |
| 2018-03-02 | 0 | 0 | 0 | 0 | 4 | 3 |
+-----------------------------------------------------------------+
如果用户尚未尝试,则得分为0且评估日期为空。我已经尝试创建一个动态数据透视表,因为使用以下准备好的语句可以根据主题改变能力数量。
SET @mysql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('(CASE WHEN score IS NOT NULL THEN score ELSE 0 END) AS `',
competency, '`')) INTO @mysql
FROM (SELECT competency, scoring_self.score FROM competency LEFT JOIN
scoring_self ON competency.competency_ID = scoring_self.competency_ID
ORDER BY competency) AS sub;
SET @mysql2= CONCAT('SELECT DISTINCT(DATE(ss.date_evaluated)) AS `Date
Evaluated`, ' , @mysql,
'FROM competency c INNER JOIN scoring_self ss
ON c.competency_ID = ss.competency_ID
GROUP BY ss.date_evaluated;');
PREPARE stmt FROM @mysql2;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
但是,我只是设法以下面的形式得到它:
+----------------+-------+-------+-------+-------+-------+--------+
| Date Evaluated | A | B | C | D | E | F |
+----------------+-------+-------+-------+-------+-------+--------+
| 2018-03-01 | 5 | 5 | 5 | 5 | 5 | 5 |
| 2018-03-02 | 4 | 4 | 4 | 4 | 4 | 4 |
+-----------------------------------------------------------------+
它似乎只是从第一次开始拉出第一组分数,我不太确定出了什么问题。任何帮助,将不胜感激!
另外,我不太确定在准备好的语句中放置WHERE子句的位置只能检索单个学生的分数。
编辑:
我已经尝试了jqueryy建议的更改,并进行了一些调整:
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('(CASE WHEN score IS NOT NULL THEN score ELSE 0 END) AS `',
competency, '`')) INTO @mysql
FROM (
SELECT competency FROM competency LEFT JOIN
scoring_self ON competency.competency_ID = scoring_self.competency_ID AND
scoring_self.student_ID=<redacted>
GROUP BY DATE(scoring_self.date_evaluated), competency) AS sub;
这给了我一个输出:
+----------------+-------+-------+-------+-------+-------+--------+
| Date Evaluated | A | B | C | D | E | F |
+----------------+-------+-------+-------+-------+-------+--------+
| 2018-03-01 | 5 | 5 | 5 | 5 | 5 | 5 |
| 2018-03-01 | 4 | 4 | 4 | 4 | 4 | 4 |
| 2018-03-02 | 4 | 4 | 4 | 4 | 4 | 4 |
| 2018-03-02 | 3 | 3 | 3 | 3 | 3 | 3 |
+-----------------------------------------------------------------+
由于超出我的原因,分数似乎没有映射到它们应该的列。
编辑2:解决了jquery的礼貌
最终准备好的陈述应该是这样的
SET @mysql_dynamic = (
SELECT
GROUP_CONCAT( DISTINCT
CONCAT(
'MAX(CASE WHEN competency = ''',
competency,
''' AND competency IS NOT NULL THEN score ELSE 0 END) AS `',
competency,
'`'
)
)
FROM (SELECT competency, scoring_self.score, student_ID FROM competency LEFT JOIN
scoring_self ON competency.competency_ID = scoring_self.competency_ID
ORDER BY competency) AS sub
);
SET @mysql = CONCAT('SELECT ss.date_evaluated, ', @mysql_dynamic, '
FROM (SELECT date_evaluated, competency, scoring_self.score, scoring_self.student_ID FROM competency LEFT JOIN
scoring_self ON competency.competency_ID = scoring_self.competency_ID
ORDER BY competency) AS ss WHERE ss.date_evaluated IS NOT NULL AND ss.student_ID = \'',<redacted>,'\' GROUP BY date_evaluated DESC');
PREPARE stmt FROM @mysql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
以上提供了可由学生ID过滤的期望结果。
我想我们接近下面的代码
这会给你想要的结果:
SET @sql_dynamic = (
SELECT
GROUP_CONCAT( DISTINCT
CONCAT(
'max(case when competency = ''',
competency,
''' and competency is not null then score end) AS `',
competency,
'`'
)
)
FROM (SELECT competency, scoring_self.score FROM competency LEFT JOIN
scoring_self ON competency.competency_ID = scoring_self.competency_ID
ORDER BY competency) AS sub
);
SET @sql = CONCAT('SELECT ss.date_evaluated,',
@sql_dynamic, '
FROM (SELECT date_evaluated, competency, scoring_self.score FROM competency LEFT JOIN
scoring_self ON competency.competency_ID = scoring_self.competency_ID
ORDER BY competency) AS ss WHERE ss.date_evaluated is not null
GROUP BY date_evaluated DESC'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
在该代码上,分数现在已正确映射到能力。
更新:
找到罪魁祸首,这是因为WHEN score IS NOT NULL THEN score ELSE 0
,尝试删除你的第一个代码上的IS NOT NULL
和ELSE 0
,这应该与你的代码正确映射列。但是首先尝试查看我的更新并测试运行。
更新:
这是我的代码,我稍微调整了一下:
SET @mysql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when competency = ''',
competency,
''' and competency is not null then score else 0 end) AS `',
competency,
'`'
)
) INTO @mysql
FROM (SELECT competency, scoring_self.score FROM competency LEFT JOIN
scoring_self ON competency.competency_ID = scoring_self.competency_ID
ORDER BY competency) AS sub;
SET @mysql2= CONCAT('SELECT DISTINCT(DATE(ss.date_evaluated)) AS `Date
Evaluated`, ' , @mysql,
'FROM competency c INNER JOIN scoring_self ss
ON c.competency_ID = ss.competency_ID
GROUP BY ss.date_evaluated;');
PREPARE stmt FROM @mysql2;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;