具有动态数据透视的Mysql查询
我有一个表名为grades,如下所示:具有动态数据透视的Mysql查询,mysql,sql,pivot-table,Mysql,Sql,Pivot Table,我有一个表名为grades,如下所示: +--------+--------+-----------+ | userid | itemid | finalgrade| +--------+--------+-----------+ | 1 | 7 | 100 | | 1 | 8 | 89 | | 2 | 7 | 87 | | 2 | 8
+--------+--------+-----------+
| userid | itemid | finalgrade|
+--------+--------+-----------+
| 1 | 7 | 100 |
| 1 | 8 | 89 |
| 2 | 7 | 87 |
| 2 | 8 | 17 |
| 3 | 7 | 87 |
| 3 | 8 | 38 |
+--------+--------+-----------+
+--------+---+---+
| userid | 7 | 8 |
+--------+---+---+
| 1 |100| 89|
| 2 |87 | 17|
| 3 |87 | 38|
+--------+---+---+
SELECT userid,
MAX(CASE WHEN itemid=7 THEN finalgrade END) as c7,
MAX(CASE WHEN itemid=8 THEN finalgrade END) as c8,
FROM grades
GROUP BY userid
SELECT
CONCAT(
'SELECT userid,',
GROUP_CONCAT(CONCAT('MAX(CASE WHEN itemid=', itemid, ' THEN finalgrade END) AS c', itemid)),
' FROM tablename GROUP BY userid')
FROM (SELECT DISTINCT itemid FROM tablename) s INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
我想创建一个pivot查询,将表更改为:
+--------+--------+-----------+
| userid | itemid | finalgrade|
+--------+--------+-----------+
| 1 | 7 | 100 |
| 1 | 8 | 89 |
| 2 | 7 | 87 |
| 2 | 8 | 17 |
| 3 | 7 | 87 |
| 3 | 8 | 38 |
+--------+--------+-----------+
+--------+---+---+
| userid | 7 | 8 |
+--------+---+---+
| 1 |100| 89|
| 2 |87 | 17|
| 3 |87 | 38|
+--------+---+---+
SELECT userid,
MAX(CASE WHEN itemid=7 THEN finalgrade END) as c7,
MAX(CASE WHEN itemid=8 THEN finalgrade END) as c8,
FROM grades
GROUP BY userid
SELECT
CONCAT(
'SELECT userid,',
GROUP_CONCAT(CONCAT('MAX(CASE WHEN itemid=', itemid, ' THEN finalgrade END) AS c', itemid)),
' FROM tablename GROUP BY userid')
FROM (SELECT DISTINCT itemid FROM tablename) s INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
我有一个解决方案,使用如下定义的itemid:
select *,
truncate (sum(finalgrade*(1-abs(sign(itemid-7)))),0) as 7,
truncate (sum(finalgrade*(1-abs(sign(itemid-8)))),0) as 8,
FROM grades
group by userid"
问题是,我需要相同的查询,但没有定义itemid,动态创建列。我想您需要这样的查询:
+--------+--------+-----------+
| userid | itemid | finalgrade|
+--------+--------+-----------+
| 1 | 7 | 100 |
| 1 | 8 | 89 |
| 2 | 7 | 87 |
| 2 | 8 | 17 |
| 3 | 7 | 87 |
| 3 | 8 | 38 |
+--------+--------+-----------+
+--------+---+---+
| userid | 7 | 8 |
+--------+---+---+
| 1 |100| 89|
| 2 |87 | 17|
| 3 |87 | 38|
+--------+---+---+
SELECT userid,
MAX(CASE WHEN itemid=7 THEN finalgrade END) as c7,
MAX(CASE WHEN itemid=8 THEN finalgrade END) as c8,
FROM grades
GROUP BY userid
SELECT
CONCAT(
'SELECT userid,',
GROUP_CONCAT(CONCAT('MAX(CASE WHEN itemid=', itemid, ' THEN finalgrade END) AS c', itemid)),
' FROM tablename GROUP BY userid')
FROM (SELECT DISTINCT itemid FROM tablename) s INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
但您希望它具有动态值,然后可以使用这样一个准备好的语句:
+--------+--------+-----------+
| userid | itemid | finalgrade|
+--------+--------+-----------+
| 1 | 7 | 100 |
| 1 | 8 | 89 |
| 2 | 7 | 87 |
| 2 | 8 | 17 |
| 3 | 7 | 87 |
| 3 | 8 | 38 |
+--------+--------+-----------+
+--------+---+---+
| userid | 7 | 8 |
+--------+---+---+
| 1 |100| 89|
| 2 |87 | 17|
| 3 |87 | 38|
+--------+---+---+
SELECT userid,
MAX(CASE WHEN itemid=7 THEN finalgrade END) as c7,
MAX(CASE WHEN itemid=8 THEN finalgrade END) as c8,
FROM grades
GROUP BY userid
SELECT
CONCAT(
'SELECT userid,',
GROUP_CONCAT(CONCAT('MAX(CASE WHEN itemid=', itemid, ' THEN finalgrade END) AS c', itemid)),
' FROM tablename GROUP BY userid')
FROM (SELECT DISTINCT itemid FROM tablename) s INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
您可以使用SUM而不是MAX,这取决于数据的结构。谢谢您的解决方案,但查询有语法错误:
您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,了解使用near“PREPARE stmt FROM@sql;执行stmt;在第8行取消分配PREPARE stmt。
@EnriqueBerrueta对我来说是正确的:itemid是INT列吗?是的,itemid是INT。我使用的是SqlFIDLE,这让我很惊讶,因为它是正确的,问题是当我在phpmyadmin或php中使用它时。@EnriqueBerrueta您有很多不同的itemid吗?group_concat有一个长度限制,我怀疑查询可能已被剪切。。。但是可以使用set group_concat_max_len=”修改此限制代码>默认值为1024,您可以尝试使用10000…是的,这对我有一点帮助,但现在查询给了我另一个错误:Unknown prepared statement handler(stmt)given to EXECUTE