美文网首页
MySQL动态行转列(列值转换列名)_后转

MySQL动态行转列(列值转换列名)_后转

作者: honest涛 | 来源:发表于2020-06-06 07:33 被阅读0次

    动态拼接的行转列SQL,如果为NULL,就会报错。

    模拟场景:课程表里没有Java课程,我们查询Java课程的成绩,成功如下:

    SET @sql = NULL;
     
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'SUM(IF(c.coursenm = ''',
          c.coursenm,
          ''', s.scores, 0)) AS ''',
          c.coursenm, ''''
        )
      ) INTO @sql
    FROM courses c WHERE c.coursenm = 'java';
     
    SET @sql = CONCAT('SELECT st.stuid, st.stunm, ', @sql, 
                            ' From Student  st 
                            LEFT JOIN score s ON st.stuid = s.stuid
                            LEFT JOIN courses c ON c.courseno = s.courseno');
                            
    SET @sql = CONCAT(@sql, ' GROUP BY st.stuid');
     
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    报错信息.png

    原因分析

    是由于课程表中没有Java这门课程,所以在拼接出的行转列SQL为NULL。因而导致出错。

    SET @sql = NULL;
     
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'SUM(IF(c.coursenm = ''',
          c.coursenm,
          ''', s.scores, 0)) AS ''',
          c.coursenm, ''''
        )
      ) INTO @sql
    FROM courses c WHERE c.coursenm = 'java';
     
    SET @sql = CONCAT('SELECT st.stuid, st.stunm, ', @sql, 
                            ' From Student  st 
                            LEFT JOIN score s ON st.stuid = s.stuid
                            LEFT JOIN courses c ON c.courseno = s.courseno');
                            
    SET @sql = CONCAT(@sql, ' GROUP BY st.stuid');
    
    -- 由于没有找到MySQL中打印sql语句到控制台的方法,所以我采用将拼接好的SQL存到临时表中进行查看。
    INSERT INTO reasons(sql_data) VALUES (@sql);
    
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    输出拼接的SQL为NULL.png

    正常情况输出的动态的SQL

    SET @sql = NULL;
     
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'SUM(IF(c.coursenm = ''',
          c.coursenm,
          ''', s.scores, 0)) AS ''',
          c.coursenm, ''''
        )
      ) INTO @sql
    FROM courses c;
     
    SET @sql = CONCAT('SELECT st.stuid, st.stunm, ', @sql, 
                            ' From Student  st 
                            LEFT JOIN score s ON st.stuid = s.stuid
                            LEFT JOIN courses c ON c.courseno = s.courseno');
                            
    SET @sql = CONCAT(@sql, ' GROUP BY st.stuid');
    
    -- 由于没有找到MySQL中打印sql语句到控制台的方法,所以我采用将拼接好的SQL存到临时表中进行查看。
    INSERT INTO reasons(sql_data) VALUES (@sql);
    
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    输出正确SQL.png 格式化后的SQL.png

    解决方法:

    增加如下SQL

    SET @sql =IFNULL(@sql,"SELECT NULL FROM DUAL");
    

    完整SQL:

    SET @sql = NULL;
     
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'SUM(IF(c.coursenm = ''',
          c.coursenm,
          ''', s.scores, 0)) AS ''',
          c.coursenm, ''''
        )
      ) INTO @sql
    FROM courses c;
     
    SET @sql = CONCAT('SELECT st.stuid, st.stunm, ', @sql, 
                            ' From Student  st 
                            LEFT JOIN score s ON st.stuid = s.stuid
                            LEFT JOIN courses c ON c.courseno = s.courseno');
                            
    SET @sql = CONCAT(@sql, ' GROUP BY st.stuid');
    
    SET @sql =IFNULL(@sql,"SELECT NULL FROM DUAL");
    
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    

    相关文章

      网友评论

          本文标题:MySQL动态行转列(列值转换列名)_后转

          本文链接:https://www.haomeiwen.com/subject/pdzgzhtx.html