【问题标题】:Select dynamic Columns in mysql在mysql中选择动态列
【发布时间】:2012-08-10 10:18:37
【问题描述】:

是否可以这样遍历表:

mysql> select * from `stackoverflow`.`Results`; +--------------+---------+-------------+--------+ |身份证 |类型 | CRITERIA_ID |结果 | +--------------+---------+-------------+--------+ | 1 |汽车 |环境 | 1 | | 2 |汽车 |气| | | 3 |汽车 |年龄 | | | 4 |自行车 |环境 | 1 | | 5 |自行车 |气| | | 6 |自行车 |年龄 | 1 | | 7 |巴士 |环境 | 1 | | 8 |巴士 |气| 1 | | 9 |巴士 |年龄 | 1 | +--------------+---------+-------------+--------+ 一组 9 行(0.00 秒)

进入这个:

+-----+---+-----+------+ |类型 |环境 |气|年龄 | +-----+---+-----+------+ |汽车 | 1 | | | |自行车 | 1 | | 1 | |巴士 | 1 | 1 | 1 | +-----+---+-----+------+

目的是选择所有CRITERIA_IDs 并将它们用作列。 作为行,我喜欢使用所有 TYPEs 。

  • 所有标准:SELECT distinct(CRITERIA_ID) FROM stackoverflow.Results;
  • 所有类型SELECT distinct(TYPE) FROM stackoverflow.Results;

但是如何将它们组合成一个视图或smth。像这样?

如果你喜欢玩数据。这是生成表格的脚本:

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 sql pivot


【解决方案1】:

不幸的是 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

【讨论】:

  • +1 用于实现准备好的语句。动态 SQL 可能被低估了。警告:不能在函数或触发器中使用。
猜你喜欢
  • 1970-01-01
  • 2012-07-26
  • 1970-01-01
  • 2018-03-12
  • 2021-10-08
  • 1970-01-01
  • 2014-10-14
  • 2013-11-04
  • 2013-01-25
相关资源
最近更新 更多