it-swarm.com.de

So transponieren / konvertieren Sie Zeilen als Spalten in MySQL

Ich habe Tabellenstrukturen wie unten Subjects Table

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

Bisher habe ich den Code geschrieben

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

Hier in meinem Skript übergebe ich die Fächernamen als fest codiert. Aber in Zukunft wissen wir nicht, wie viele Fächer in Klasse 13 haben werden. Wo soll ich meine Abfrage ändern, um die Betreff-IDs anstelle der Betreffnamen zu übergeben, und das auch nicht als fest codiert.

Kann ich alle Betreff-IDs für eine bestimmte Klasse in eine Variable aufnehmen und die Max (Case) -Anweisung übergeben? Ist es möglich?

Bitte überprüfen Sie meinen Code und geben Sie mir einen Hinweis/eine Hilfe, um diesen Code zu bearbeiten.

Vielen Dank im Voraus.

4
Narendar_CH

Dazu müssen Sie dynamisches SQL verwenden.

Um die Dinge auf der Clientseite zu vereinfachen, ist es besser, sie in eine gespeicherte Prozedur zu packen. In Ihrem Fall könnte ein solches Verfahren so aussehen

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 ;

Hinweis: VERBINDET mit tbl_classes und tbl_subjects wurden entfernt, da Sie nichts von der ersteren abrufen und später keine bedingte Gruppierung benötigen (stattdessen verwendete IDs).

Dann tun Sie es auf der Client-Seite einfach

CALL sp_exam(13, 2);

Beispielausgabe:

 | ROLLNO | STDNM | TELUGU2 | TELUGU3 | HINDI1 | DEUTSCH2 | DEUTSCH3 | MATHS2 | MATHS3 | PHYSIK1 | BIOLOGIE1 | SOZIAL2 | SOCIAL3 | 
 --------------------------------------- -------------------------------------------------- ---------------------------------------- 
 | 1 | Student 1 | 45 | 32 | 80 | 39 | 41 | 34 | 32 | 31 | 33 | 35 | 43 | 
 | 2 | Student 2 | 40 | 33 | 89 | 38 | 45 | 38 | 33 | 34 | 31 | 31 | 38 | 

Hier ist SQLFiddle Demo

7
peterm