【问题标题】:select row values to be column titles in mysql select [duplicate]选择行值作为mysql中的列标题选择[重复]
【发布时间】:2013-11-28 11:17:50
【问题描述】:

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
.
.
.        

股东人数不固定

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    为此使用动态 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 |日期 |数量 |哈利 |马克 |理查德 | |----|------------|--------|--------|-- ----|----------| | 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 |

    这里是SQLFiddle演示


    为了简化调用端的事情,您可以将其包装在存储过程中

    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演示

    【讨论】:

    • 非常感谢@peterm,它就像一个魅力!
    • @indago 不客气。祝你好运:)
    • 我遇到了一个问题,我可以用上面的代码创建一个视图吗?创建视图时出现错误。 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET @sql = NULL' at line 2
    • @indago 不,你不能。 MySQL 既不允许在FROM 中使用子查询,也不允许在动态 SQL(PREPARE 和所有)中使用
    猜你喜欢
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-30
    • 2014-10-14
    • 2011-12-29
    相关资源
    最近更新 更多