mysql - 在mysql中选择动态列

标签 mysql sql pivot

是否可以像这样遍历一个表:

mysql> select * from `stackoverflow`.`Results`;
+--------------+---------+-------------+--------+
| ID           | TYPE    | CRITERIA_ID | RESULT |
+--------------+---------+-------------+--------+
|            1 | car     | env         | 1      |
|            2 | car     | gas         |        |
|            3 | car     | age         |        |
|            4 | bike    | env         | 1      |
|            5 | bike    | gas         |        |
|            6 | bike    | age         | 1      |
|            7 | bus     | env         | 1      |
|            8 | bus     | gas         | 1      |
|            9 | bus     | age         | 1      |
+--------------+---------+-------------+--------+
9 rows in set (0.00 sec)

Into this:

+------+-----+-----+-----+
| TYPE | env | gas | age |
+------+-----+-----+-----+
| car  | 1   |     |     |
| bike | 1   |     | 1   |
| bus  | 1   | 1   | 1   |
+------+-----+-----+-----+

The aim is to select all the CRITERIA_IDs and use them as a column. As rows i like to use all the TYPEs .

  • All Criterias: SELECT distinct(CRITERIA_ID) FROM stackoverflow.Results;
  • All Types SELECT distinct(TYPE) FROM stackoverflow.Results;

But how combine them into a view or smth. like this?

If you like to play with the data. This is a script to generate the table:

CREATE SCHEMA `stackoverflow`;
CREATE TABLE `stackoverflow`.`Results` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `TYPE` varchar(50) NOT NULL,
  `CRITERIA_ID` varchar(5) NOT NULL,
  `RESULT` bit(1) NOT NULL,
  PRIMARY KEY (`ID`)
) 
ENGINE=InnoDB;

INSERT INTO `stackoverflow`.`Results`
(
 `ID`,
 `TYPE`,
 `CRITERIA_ID`,
 `RESULT`
)
VALUES
( 1, "car", env, true ),
( 2, "car", gas, false ),
( 3, "car", age, false ),
( 4, "bike", env, true ),
( 5, "bike", gas, false ),
( 6, "bike", age, true ),
( 7, "bus", env, true ),
( 8, "bus", gas, true ),
( 9, "bus", age, true );

最佳答案

不幸的是,MySQL 没有 PIVOT 函数,这基本上就是您要尝试做的。因此,您需要使用带有 CASE 语句的聚合函数:

SELECT type,
  sum(case when criteria_id = 'env' then result end) env,
  sum(case when criteria_id = 'gas' then result end) gas,
  sum(case when criteria_id = 'age' then result end) age
FROM results
group by type

参见 SQL Fiddle with Demo

现在,如果您想动态地执行此操作,这意味着您事先不知道要转置的列,那么您应该查看以下文章:

Dynamic pivot tables (transform rows to columns)

您的代码如下所示:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(IF(CRITERIA_ID = ''',
      CRITERIA_ID,
      ''', RESULT, NULL)) AS ',
      CRITERIA_ID
    )
  ) INTO @sql
FROM
  Results;
SET @sql = CONCAT('SELECT type, ', @sql, ' FROM Results GROUP BY type');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

参见 SQL Fiddle with Demo

关于mysql - 在mysql中选择动态列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11899647/

相关文章:

大表连接的mysql查询优化

php - 多个列表功能无法正常工作 php

python - 通过 SQLAlchemy 执行 Teradata MERGE 时不会产生任何结果

c# - 配置弹性设置 Entity Framework 6.02

SQL Server 2008 - 从另一个表动态创建一个表

MySQL 将行转为动态数量的列

python - 从 Pivot reshape 和选择 Pandas

mysql - 导入大数据库到docker时写入错误

mysql - 当使用数据库指定时,Docker mysql 容器不会创建带有密码的用户

javascript - 像 SQL 中一样加入 Json