数据透视表有3个表

时间:2012-10-20 08:44:39

标签: mysql sql pivot

我正在尝试从三个表生成一个数据透视视图:

  1. 学生
  2. stud_fee(关系表)
  3. 表格:

    Students Table
    +----+-----------+-----------+----------------+----------------+-------+
    | id | school_id | last_name | first_name     | middle_initial | yrlvl |
    +----+-----------+-----------+----------------+----------------+-------+
    |  1 | 2080295   | Doe       | John           | A              |     3 |
    |  2 | 0239129   | Rizal     | Jose           | M              |     4 |
    |  3 | 1231238   | Santos    | Jane           | M              |     2 |
    +----+-----------+-----------+----------------+----------------+-------+
    
    Fee table
    +----+--------------------+------------+
    | id | fee_name           | fee_amount |
    +----+--------------------+------------+
    |  1 | Registration Fee   |        100 |
    |  2 | News Letter        |        100 |
    |  3 | T-Shirt            |        250 |
    |  4 | Party              |        500 |
    +----+--------------------+------------+
    
    stud_fee table
    +----+------------+-----+
    | id | stud_id | fee_id |
    +----+---------+--------+
    |  1 |       1 |      1 |
    |  2 |       1 |      2 |
    |  3 |       1 |      3 |
    |  4 |       2 |      1 |
    |  5 |       3 |      1 |
    |  6 |       3 |      4 |
    +----+---------+--------+
    

    我想将费用作为列和学生作为行。 我想把它显示为:

    +-----------+------------------+-------------+---------+-------+-------+
    | school_id | Registration Fee | News Letter | T-Shirt | Party | Total |
    +-----------+------------------+-------------+---------+-------+-------+
    | 2080295   |              100 |         100 |     250 |       |   450 |
    | 0239129   |              100 |             |         |       |   100 |
    | 1231238   |              100 |             |         |   500 |   600 |
    +-----------+------------------+-------------+---------+-------+-------+
    

2 个答案:

答案 0 :(得分:4)

看起来您可能会有未知数量的费用要转换为列,如果是这种情况,那么您将需要使用预准备语句来查询:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when f.fee_name = ''',
      f.fee_name,
      ''' then f.fee_amount else 0 end) AS `',
      f.fee_name, '`'
    )
  ) INTO @sql
FROM fee f;

SET @sql = CONCAT('SELECT s.school_id, ', @sql, '
                    , sum(f.fee_amount) as Total
                  FROM students s
                  LEFT JOIN stud_fee sf
                    on s.id = sf.stud_id
                  LEFT JOIN fee f
                    on sf.fee_id = f.id
                   GROUP BY s.school_id');


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

请参阅SQL Fiddle with Demo

答案 1 :(得分:2)

试试这个:

SELECT 
  s.school_id,
  MAX(CASE WHEN f.fee_name = 'Registration Fee' THEN f.fee_amount END) 
    AS 'Registration Fee',
  MAX(CASE WHEN f.fee_name = 'News Letter'      THEN f.fee_amount END) 
    AS 'News Letter',
  MAX(CASE WHEN f.fee_name = 'T-Shirt'          THEN f.fee_amount END) 
    AS 'T-Shirt',
  MAX(CASE WHEN f.fee_name = 'Party'            THEN f.fee_amount END) 
    AS 'Party',
  SUM(f.fee_amount) AS Total
FROM Students s
INNER JOIN stud_fee sf 
        ON s.Id = sf.stud_id
INNER JOIN fee f       
       ON sf.fee_id = f.id
GROUP BY s.school_id

SQL Fiddle Demo