mysql - 选择行值作为 mysql select 中的列标题

标签 mysql sql

我在 MySql 中有两个表,

shareholders     

    id  name   value
     1  harry    20
     2  mark     60
     3  richard  20

第二个表是

transactions    
     id   date          amount
      1   2013-11-01    2000
      2   2013-11-01    150
      3   2013-11-01    300
      4   2013-11-02    700
      5   2013-11-02    5400

第一个表包含交易金额分配的百分比。 MySQL 中是否有可能有一个选择查询返回以下输出?

transid    amount    harry   mark   richard ,.....
1          2000      400     1200    400
2          150        30       90     30
3          300        60      180     60
.
.
.        

股东人数不固定

最佳答案

为此使用动态 SQL

SET @sql = NULL;

SELECT GROUP_CONCAT(CONCAT(
          'MAX(CASE WHEN h.id = ', id, 
          ' THEN amount * ', value / 100, 
          ' END) `', name, '`'))
  INTO @sql
  FROM shareholders;

SET @sql = CONCAT(
              'SELECT t.id transaction_id, t.date, t.amount, ', @sql, 
              '  FROM transactions t CROSS JOIN shareholders h 
                GROUP BY t.id');

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

输出:

| TRANSACTION_ID |       DATE | AMOUNT | HARRY | MARK | RICHARD |
|----------------|------------|--------|-------|------|---------|
|              1 | 2013-11-01 |   2000 |   400 | 1200 |     400 |
|              2 | 2013-11-01 |    150 |    30 |   90 |      30 |
|              3 | 2013-11-01 |    300 |    60 |  180 |      60 |
|              4 | 2013-11-02 |    700 |   140 |  420 |     140 |
|              5 | 2013-11-02 |   5400 |  1080 | 3240 |    1080 |

Here is SQLFiddle demo


To simplify things on the calling end you can wrap it up in a stored procedure

DELIMITER $$
CREATE PROCEDURE shareholders_report()
BEGIN
  SET @sql = NULL;

  SELECT GROUP_CONCAT(CONCAT(
            'MAX(CASE WHEN h.id = ', id, 
            ' THEN amount * ', value / 100, 
            ' END) `', name, '`'))
    INTO @sql
    FROM shareholders;

  SET @sql = CONCAT(
                'SELECT t.id transaction_id, t.date, t.amount, ', @sql, 
                '  FROM transactions t CROSS JOIN shareholders h 
                  GROUP BY t.id');

  PREPARE stmt FROM @sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;

然后使用它:

CALL shareholders_report();

这里是SQLFiddle 演示

关于mysql - 选择行值作为 mysql select 中的列标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19994718/

相关文章:

mysql - 将 Mac 上的 MAMP 链接到 MySQL 和 phpMyAdmin 的不同实例

MySQL PDO 子查询构造帮助 - 以前从未这样做过

mysql - 杀死所有正在运行的线程

mysql - MySQL 中的上一行值

python - Paradox 数据库转换 python

sql - Like Operator 检索结果

MySQL:通过多个值的分组获取具有最高时间戳的行

mysql - 如何汇总只出现一次的行?

MYSQL GROUP BY 和 WHERE 子句

sql - 在 postgresql 函数中使用数组运算符