MYSQL从每列中删除空值

时间:2015-10-09 04:45:08

标签: mysql

我正在尝试创建一个sp,它通过检索每个字段中每个值的计数来对表中的数据进行概要分析。我遇到的问题是它通过执行一系列联合来构建一个配置文件表。我目前的结果如下面的结果1。

我的问题是:我是否可以使用select语句使结果看起来像结果2,或者可能是我构建表而不是使用联合的更好方法?

结果1

Col1      Col1_cnt   Col2   Col2_cnt    Col3    Col3_cnt
Family     15       <NULL>  <NULL>     <NULL>   <NULL>
Friend      4       <NULL>  <NULL>     <NULL>   <NULL>
Coworker    3       <NULL>  <NULL>     <NULL>   <NULL>
<NULL>    <NULL>    <NULL>    23       <NULL>   <NULL>
<NULL>    <NULL>    John      15       <NULL>   <NULL>
<NULL>    <NULL>    Jane       4       <NULL>   <NULL>
<NULL>    <NULL>    <NULL>  <NULL>     <NULL>     8
<NULL>    <NULL>    <NULL>  <NULL>     Work       3
<NULL>    <NULL>    <NULL>  <NULL>     School     2
<NULL>    <NULL>    <NULL>  <NULL>     Social     1
<NULL>    <NULL>    <NULL>  <NULL>     Conf       5

期望结果2

Col1    Col1_cnt    Col2    Col2_cnt    Col3    Col3_cnt
Family    15        <NULL>    23        <NULL>    8
Friend     4        John      15        Work      3
Coworker   3        Jane       4        School    2
<NULL>   <NULL>     <NULL>   <NULL>     Social    1
<NULL>   <NULL>     <NULL>   <NULL>     Conf      5

这是我创建的sp:

DROP PROCEDURE IF EXISTS my_db.usp_profile_data;
DELIMITER $$
CREATE PROCEDURE my_db.usp_profile_data(IN vdb_name VARCHAR(255), IN vtbl_name VARCHAR(255))

BEGIN
#CREATES TEMP TABLE TO HOUSE SCHEMA DATA
DROP TABLE IF EXISTS my_db.profile_data;
CREATE TEMPORARY TABLE my_db.profile_data
(id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
    #ord_position INT,
    col_name VARCHAR(255),
    col_type VARCHAR(255));

#INSERTS COLUMNS OF DB AND TABLE PASSED EXCLUDING SYS FIELDS
INSERT INTO my_db.profile_data(col_name, col_type)
SELECT COLUMN_NAME, 
    COLUMN_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = vdb_name
AND table_name = vtbl_name
AND EXTRA <> ('auto_increment')
AND COLUMN_NAME NOT IN('update_dt','credate_dt');

#DROP PROFILE TABLE IF ALREADY EXISTS
DROP TABLE IF EXISTS my_db.profile_data_FIN;

#INITIALIZES LOOP VARIABLE
SELECT COUNT(*)
FROM  my_db.profile_data
INTO @vLoop;

#INITIALIZE INCREMENT VARIABLE
SET @vInc =1;

#BEGIN LOOP THROUGH FIELDS
WHILE @vInc <= (@vLoop) DO


   #STORES COLUMN NAME AND DATA TYPE TO BE USED IN CREATING THE PROFILE TABLE
   SELECT col_name,
                col_type
    FROM my_db.profile_data
    WHERE id = @vInc
    INTO @vColName,@vColType;

    #IF FIRST PASS CREATE THE TABLE, ELSE ADD COLUMNS
    IF (@vInc = 1) THEN 
        SET @vSQL_Tbl = CONCAT('CREATE TEMPORARY TABLE my_db.profile_data_FIN (',@vColName,' ',@vColType,', cnt_',@vColName,' INT)');
    ELSE
        SET @vSQL_Tbl = CONCAT('ALTER TABLE my_db.profile_data_FIN ADD COLUMN ',@vColName,' ',@vColType,', ADD COLUMN cnt_',@vColName,' INT');
    END IF;

    #EXECUTES THE DYNAMIC TABLE STATEMENT
     PREPARE stmtTbl FROM @vSQL_Tbl;

        EXECUTE stmtTbl;

    DEALLOCATE PREPARE stmtTbl;

    #CREATES SQL QUERY USED TO POPULATE THE PROFILE TABLE
    SET @vSQL = CONCAT('INSERT INTO my_db.profile_data_FIN (', @vColName,', cnt_',@vColName,')', 'SELECT ',@vColName,', COUNT(*) AS cnt_',@vColName,' FROM ',vdb_name ,'.', vtbl_name,' GROUP BY ',  @vColName, ' ORDER BY 2 DESC');

   #EXECUTES THE POPULATION OF THE PROFILE TABLE
   PREPARE stmtQry FROM @vSQL;

        EXECUTE stmtQry;

    DEALLOCATE PREPARE stmtQry;

    #SELECT @vSQL;

    SET @vInc =@vInc+1;

END WHILE;


SELECT *
FROM my_db.profile_data_FIN;

END$$
DELIMITER ;

1 个答案:

答案 0 :(得分:1)

尝试以下查询 -

您可以在此处查看sqlfiddle

SELECT a.s_no,a.col1,a.col1_cnt,b.col2,b.col2_cnt,c.col3,c.col3_cnt FROM 
(SELECT a.s_no,b.col1,b.col1_cnt FROM (SELECT 1 AS s_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a LEFT JOIN (SELECT @n := @n + 1 AS s_no1,col1,col1_cnt FROM mytable a JOIN (SELECT @n := 0) m WHERE col1_cnt IS NOT NULL) b ON a.s_no=b.s_no1) a 
LEFT JOIN (SELECT @n2 := @n2 + 1 AS s_no,col2,col2_cnt FROM mytable a JOIN (SELECT @n2 := 0) m2 WHERE col2_cnt IS NOT NULL) b
ON a.s_no=b.s_no 
LEFT JOIN (SELECT @n3 := @n3 + 1 AS s_no,col3,col3_cnt FROM mytable a JOIN (SELECT @n3 := 0) m3 WHERE col3_cnt IS NOT NULL) c 
ON a.s_no=c.s_no 
where c.col3_cnt is not null 
ORDER BY a.s_no;