如何在mysql中将行转置/转换为列

Nar*_*_CH 4 mysql

我的表结构如下图所示 主题表

      +----+------+------+--------+---------+
      | id | C_Id | G_Id | status | subject |
      +----+------+------+--------+---------+
      |  1 |   13 |    4 |      1 | Telugu  |
      |  2 |   13 |    4 |      1 | Hindi   |
      |  3 |   13 |    4 |      1 | English |
      |  4 |   13 |    4 |      1 | Maths   |
      |  5 |   13 |    4 |      1 | Physics |
      |  6 |   13 |    4 |      1 | Biology |
      |  7 |   13 |    4 |      1 | Social  |
      +----+------+------+--------+---------+ 

      +----+-----+-----+--------+--------+-------+-------+-------+
      | id | Cid | Gid | Examid | rollno | subId | Marks | paper |
      +----+-----+-----+--------+--------+-------+-------+-------+
      |  1 |  13 |   4 |      1 |      1 |     1 | 14.50 |     1 |
      |  2 |  13 |   4 |      1 |      2 |     1 | 12.00 |     1 |
      |  3 |  13 |   4 |      1 |      1 |     2 | 13.00 |     1 |
      |  4 |  13 |   4 |      1 |      2 |     2 | 15.00 |     1 |
      |  5 |  13 |   4 |      1 |      1 |     3 | 16.00 |     1 |
      |  6 |  13 |   4 |      1 |      2 |     3 | 18.00 |     1 |
      |  7 |  13 |   4 |      1 |      1 |     4 | 19.00 |     1 |
      |  8 |  13 |   4 |      1 |      2 |     4 | 23.00 |     1 |
      |  9 |  13 |   4 |      1 |      1 |     5 | 21.00 |     1 |
      | 10 |  13 |   4 |      1 |      2 |     5 | 24.00 |     1 |
      | 11 |  13 |   4 |      1 |      1 |     6 | 20.00 |     1 |
      | 12 |  13 |   4 |      1 |      2 |     6 | 19.00 |     1 |
      | 13 |  13 |   4 |      1 |      1 |     7 | 20.00 |     1 |
      | 14 |  13 |   4 |      1 |      2 |     7 | 21.00 |     1 |
      | 15 |  13 |   4 |      2 |      1 |     1 | 45.00 |     2 |
      | 16 |  13 |   4 |      2 |      2 |     1 | 40.00 |     2 |
      | 17 |  13 |   4 |      2 |      1 |     1 | 32.00 |     3 |
      | 18 |  13 |   4 |      2 |      2 |     1 | 33.00 |     3 |
      | 19 |  13 |   4 |      2 |      1 |     2 | 80.00 |     1 |
      | 20 |  13 |   4 |      2 |      2 |     2 | 89.00 |     1 |
      | 21 |  13 |   4 |      2 |      1 |     3 | 39.00 |     2 |
      | 22 |  13 |   4 |      2 |      2 |     3 | 38.00 |     2 |
      | 23 |  13 |   4 |      2 |      1 |     3 | 41.00 |     3 |
      | 24 |  13 |   4 |      2 |      2 |     3 | 45.00 |     3 |
      | 25 |  13 |   4 |      2 |      1 |     4 | 34.00 |     2 |
      | 26 |  13 |   4 |      2 |      2 |     4 | 38.00 |     2 |
      | 27 |  13 |   4 |      2 |      1 |     4 | 32.00 |     3 |
      | 28 |  13 |   4 |      2 |      2 |     4 | 33.00 |     3 |
      | 29 |  13 |   4 |      2 |      1 |     5 | 31.00 |     1 |
      | 30 |  13 |   4 |      2 |      2 |     5 | 34.00 |     1 |
      | 31 |  13 |   4 |      2 |      1 |     6 | 33.00 |     1 |
      | 32 |  13 |   4 |      2 |      2 |     6 | 31.00 |     1 |
      | 33 |  13 |   4 |      2 |      1 |     7 | 35.00 |     2 |
      | 34 |  13 |   4 |      2 |      2 |     7 | 31.00 |     2 |
      | 35 |  13 |   4 |      2 |      1 |     7 | 43.00 |     3 |
      | 36 |  13 |   4 |      2 |      2 |     7 | 38.00 |     3 |
      +----+-----+-----+--------+--------+-------+-------+-------+ 
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经编写了代码

select ta.rollno,
ta.StdNm,
max(case when s.subject = 'Telugu' AND tm.paper=1 then tm.Marks end) Telugu,
max(case when s.subject = 'Telugu' AND tm.paper=2 then tm.Marks end) Telugu1,
max(case when s.subject = 'Telugu' AND tm.paper=3 then tm.Marks end) Telugu2,
max(case when s.subject = 'Hindi' AND tm.paper=1 then tm.Marks end) Hindi,
max(case when s.subject = 'Hindi' AND tm.paper=2 then tm.Marks end) Hindi1,
max(case when s.subject = 'Hindi' AND tm.paper=3 then tm.Marks end) Hindi2,
max(case when s.subject = 'English' AND tm.paper=1 then tm.Marks end) English,
max(case when s.subject = 'English' AND tm.paper=2 then tm.Marks end) English1,
max(case when s.subject = 'English' AND tm.paper=3 then tm.Marks end) English2,
max(case when s.subject = 'Maths' AND tm.paper=1 then tm.Marks end) Maths,
max(case when s.subject = 'Maths' AND tm.paper=2 then tm.Marks end) Maths1,
max(case when s.subject = 'Maths' AND tm.paper=3 then tm.Marks end) Maths2,
max(case when s.subject = 'Physics' AND tm.paper=1 then tm.Marks end) Physics,
max(case when s.subject = 'Physics' AND tm.paper=2 then tm.Marks end) Physics1,
max(case when s.subject = 'Physics' AND tm.paper=3 then tm.Marks end) Physics2,
max(case when s.subject = 'Biology' AND tm.paper=1 then tm.Marks end) Biology,
max(case when s.subject = 'Biology' AND tm.paper=2 then tm.Marks end) Biology1,
max(case when s.subject = 'Biology' AND tm.paper=3 then tm.Marks end) Biology2,
max(case when s.subject = 'Social' AND tm.paper=1 then tm.Marks end) Social,
max(case when s.subject = 'Social' AND tm.paper=2 then tm.Marks end) Social1,
max(case when s.subject = 'Social' AND tm.paper=3 then tm.Marks end) Social2
FROM tbl_cmarks tm
INNER JOIN tbl_classes tc
 ON tm.Cid = tc.C_Id
INNER JOIN tbl_admission ta
 ON ta.rollno = tm.rollno
INNER JOIN tbl_subjects s
 on tm.subId = s.id
where tm.Cid = 13 
and tm.Examid=2
group by  ta.rollno
Run Code Online (Sandbox Code Playgroud)

在我的脚本中,我将科目名称作为硬编码传递但将来我们不知道第 13 类中会有多少科目,我应该在哪里更改查询以传递科目 ID 而不是科目名称,这也不是硬编码。

我可以将特定类的所有主题 ID 放入一个变量中并传入 Max(Case) 语句。?是否可以?

请查看我的代码并给我一个提示/帮助,以完成此代码的工作。

先感谢您。

pet*_*erm 7

为此,您必须使用动态 SQL。

为了简化客户端的事情,最好将其包装在存储过程中。在你的情况下,这样的程序可能看起来像

DELIMITER $$
CREATE PROCEDURE sp_exam(IN _cid INT, IN _examid INT)
BEGIN
    SET SESSION group_concat_max_len = (7 * 1024);

    SET @sql = NULL;

    SELECT GROUP_CONCAT(DISTINCT
             CONCAT(
               'MAX(CASE WHEN m.subid = ', subid,
               ' AND m.paper = ', paper, 
               ' THEN m.marks END) ', subject, paper))
      INTO @sql
      FROM tbl_cmarks m JOIN tbl_subjects s 
        ON m.subid = s.id
     WHERE cid = _cid
       AND examid = _examid;

    SET @sql = CONCAT(
                 'SELECT a.rollno, a.stdnm, ', @sql,  
                  ' FROM tbl_cmarks m JOIN tbl_admission a
                      ON m.rollno = a.rollno 
                   WHERE m.cid = ', _cid, 
                   ' AND m.examid = ', _examid,
                 ' GROUP BY a.rollno, a.stdnm');

    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

注意:使用tbl_classes和 的JOINtbl_subjects已被删除,因为您不从前者获取任何内容,并且以后不需要条件分组(改为使用 id)。

然后在客户端你就做

CALL sp_exam(13, 2);
Run Code Online (Sandbox Code Playgroud)

示例输出:

| 罗诺 | 标准网 | 泰卢固语2 | 泰卢固语3 | 印地语1 | 英文2 | 英文3 | 数学2 | 数学3 | 物理1 | 生物学1 | 社会 2 | 社会3 |
-------------------------------------------------- -------------------------------------------------- ---------------------------------
| 1 | 学生 1 | 45 | 32 | 80 | 39 | 41 | 34 | 32 | 31 | 33 | 35 | 43 |
| 2 | 学生 2 | 40 | 33 | 89 | 38 | 45 | 38 | 33 | 34 | 31 | 31 | 38 |

这是SQLFiddle演示