如何获取带有填充计数的MYSQL信息模式列名?

时间:2018-06-05 06:11:31

标签: mysql

我试图从MYSQL中的信息模式中获取特定表的所有列名,我做得非常好。

现在我想在其名称前面追加每列填写的数量(列不应为空)。

这是我的问题:

SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'hr_db'
AND table_name = "employee_tbl"

以上查询结果为:

COLUMN_NAME
+-----------
id
------------
name
------------
phone
------------
email

但我想要的是如下:

COLUMN_NAME   COUNT
+------------------
id            20
-------------------
name          20
-------------------
phone         12
-------------------
email         5

提前感谢您的意见和回答

2 个答案:

答案 0 :(得分:2)

使用预准备语句获取一行总计相对容易 例如

set @sql = (
concat('select ',
(
select group_concat(concat('count(',column_name,') as ',column_name)) 
from information_schema.columns
where table_name = 'users' and table_schema = 'sandbox'
)
, ' from users')
);

prepare sqlstmt from @sql;
execute sqlstmt;
deallocate prepare sqlstmt;

+----+------+----------+-------+-----------+----------+-----+-----+------------+----+
| id | name | password | email | firstname | lastname | sal | age | event_date | ts |
+----+------+----------+-------+-----------+----------+-----+-----+------------+----+
|  6 |    3 |        2 |     0 |         1 |        3 |   2 |   0 |          4 |  6 |
+----+------+----------+-------+-----------+----------+-----+-----+------------+----+
1 row in set (0.00 sec)

如果你想要每列1行,那么因为mysql没有univot功能,你可以

drop procedure if exists p;
delimiter $$
create procedure p(inschema varchar(100), intable varchar(100))
begin

declare cname varchar(100);
declare done int default false;

DECLARE cur CURSOR FOR
        SELECT column_name from information_schema.columns
        where table_schema = inschema and table_name = intable
          order by ordinal_position;

DECLARE CONTINUE handler FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    set @sql = '';
    LOOP1: LOOP
        #set no_more_rows1 = false;
        FETCH cur INTO cname;
        IF done THEN
            CLOSE cur;
            LEAVE LOOP1;
        END IF;

        set @sql = concat(@sql, 'select ', char(39),cname,char(39), ', count(', cname, ') as count from ' , intable, ' union ');

    END LOOP LOOP1; 
     set @sql = concat(substring(@sql,1,length(@sql) - 7),';');    
    prepare sqlstmt from @sql;
    execute sqlstmt;
    deallocate prepare sqlstmt;
end $$
delimiter ;


call p('sandbox','users');
+------------+-------+
| id         | count |
+------------+-------+
| id         |     6 |
| name       |     3 |
| password   |     2 |
| email      |     0 |
| firstname  |     1 |
| lastname   |     3 |
| sal        |     2 |
| age        |     0 |
| event_date |     4 |
| ts         |     6 |
+------------+-------+
10 rows in set (0.03 sec)

或者,如果您不喜欢某个程序,那么

set @sql = 
(
select group_concat(concat('select ' ,char(39),column_name,char(39), ',count(' , column_name, ') from users union ' ))
from information_schema.`COLUMNS` where table_schema = 'sandbox' and table_name = 'users'
);

set @sql = replace(@sql,'union ,','union ');

set @sql = concat(substring(@sql,1,length(@sql) - 7),';'); 
prepare sqlstmt from @sql;
execute sqlstmt;
deallocate prepare sqlstmt;

答案 1 :(得分:0)

您可以通过常规选择来实现:

SELECT COUNT(`id`), COUNT(`name`), COUNT(`phone`), COUNT(`email`) FROM `employee_tbl`;