Mysql 从表中仅选择具有null/empty值的列

Mysql 从表中仅选择具有null/empty值的列,mysql,sql,null,Mysql,Sql,Null,我有一个看起来像这样的数据集,但是列继续作为data4、data5到data20 id data1 data2 data3 (int) (varchar) (int) (date) ------------------------------------- 1 xyz (null) 0000-00-00 2 (empty) 321 2013-09-02 3

我有一个看起来像这样的数据集,但是列继续作为data4、data5到data20

id      data1       data2       data3
(int)   (varchar)   (int)       (date)
-------------------------------------
1       xyz         (null)      0000-00-00
2       (empty)     321         2013-09-02
3       abc         555         2013-02-29
4       def         (null)      2013-09-02
5       lmn         678         2013-03-19
我只想选择列为null或空的行,这样客户就可以决定需要在他们的票据中填写哪些字段

data1       data2       data3
(varchar)   (int)       (date)
-------------------------------------
2            1,4          1,5

或者如果有人能想出更好的变异?我现在对任何事情都持开放态度,只要它在做我想要的工作。这可能吗?谢谢

考虑到您最多有20个数据列,这可能是一个坏主意,但您希望这样做吗

SELECT * FROM
    (SELECT GROUP_CONCAT(id) data1 FROM foo WHERE data1 IS NULL OR data1 = '') AS f1,
    (SELECT GROUP_CONCAT(id) data2 FROM foo WHERE data2 IS NULL OR data2 = '') AS f2,
    (SELECT GROUP_CONCAT(id) data3 FROM foo WHERE data3 IS NULL OR data3 = '') AS f3

考虑到您最多有20个数据列,这可能是一个坏主意,但您是否希望这样做

SELECT * FROM
    (SELECT GROUP_CONCAT(id) data1 FROM foo WHERE data1 IS NULL OR data1 = '') AS f1,
    (SELECT GROUP_CONCAT(id) data2 FROM foo WHERE data2 IS NULL OR data2 = '') AS f2,
    (SELECT GROUP_CONCAT(id) data3 FROM foo WHERE data3 IS NULL OR data3 = '') AS f3

您可以使用动态SQL这样做

DELIMITER $$
CREATE PROCEDURE sp_empty()
BEGIN
  SET @sql = NULL;

  SELECT GROUP_CONCAT(
           CONCAT('(SELECT GROUP_CONCAT(id) FROM Table1 WHERE `', 
                  column_name, '` IS NULL ',
                  CASE  
                    WHEN data_type IN('varchar', 'char') 
                      THEN CONCAT('OR `', column_name, '` = ''''')
                    WHEN data_type IN('date', 'datetime', 'time') 
                      THEN CONCAT('OR `', column_name, '` = 0')
                    ELSE ''
                  END, ')`', column_name, '`'))
     INTO @sql
    FROM INFORMATION_SCHEMA.COLUMNS
   WHERE table_schema = SCHEMA()
     AND table_name = 'table1'
     AND column_name NOT IN ('id')
   GROUP BY table_name;

  SET @sql = CONCAT('SELECT ', @sql);

  PREPARE stmt FROM @sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
注意,它负责不同数据类型的列

示例用法:

CALL sp_empty();
输出:

| DATA1 | DATA2 | DATA3 | |-------|-------|-------| | 2 | 1,4 | 1 | 这里是演示


如果出于某种原因,您不能使用带有动态SQL的版本,那么作为最后的手段,您可以自己生成这样的查询,包括所有列

SELECT 
(
  SELECT GROUP_CONCAT(id) 
     FROM Table1 
    WHERE `data1` IS NULL 
       OR `data1` = ''
) `data1`,
(
  SELECT GROUP_CONCAT(id) 
    FROM Table1 
   WHERE `data2` IS NULL
) `data2`,
(
  SELECT GROUP_CONCAT(id) 
    FROM Table1 
   WHERE `data3` IS NULL 
      OR `data3` = 0
) `data3`
...

下面是演示

您可以用动态SQL这样做

DELIMITER $$
CREATE PROCEDURE sp_empty()
BEGIN
  SET @sql = NULL;

  SELECT GROUP_CONCAT(
           CONCAT('(SELECT GROUP_CONCAT(id) FROM Table1 WHERE `', 
                  column_name, '` IS NULL ',
                  CASE  
                    WHEN data_type IN('varchar', 'char') 
                      THEN CONCAT('OR `', column_name, '` = ''''')
                    WHEN data_type IN('date', 'datetime', 'time') 
                      THEN CONCAT('OR `', column_name, '` = 0')
                    ELSE ''
                  END, ')`', column_name, '`'))
     INTO @sql
    FROM INFORMATION_SCHEMA.COLUMNS
   WHERE table_schema = SCHEMA()
     AND table_name = 'table1'
     AND column_name NOT IN ('id')
   GROUP BY table_name;

  SET @sql = CONCAT('SELECT ', @sql);

  PREPARE stmt FROM @sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
注意,它负责不同数据类型的列

示例用法:

CALL sp_empty();
输出:

| DATA1 | DATA2 | DATA3 | |-------|-------|-------| | 2 | 1,4 | 1 | 这里是演示


如果出于某种原因,您不能使用带有动态SQL的版本,那么作为最后的手段,您可以自己生成这样的查询,包括所有列

SELECT 
(
  SELECT GROUP_CONCAT(id) 
     FROM Table1 
    WHERE `data1` IS NULL 
       OR `data1` = ''
) `data1`,
(
  SELECT GROUP_CONCAT(id) 
    FROM Table1 
   WHERE `data2` IS NULL
) `data2`,
(
  SELECT GROUP_CONCAT(id) 
    FROM Table1 
   WHERE `data3` IS NULL 
      OR `data3` = 0
) `data3`
...

这里是演示

你能发布你尝试过的吗?你能发布你尝试过的吗?动态SQL看起来很不错。。。。但不幸的是,我只限于标准的本机SQL查询。。。如蒙更多帮助,我们将不胜感激。。谢谢@user1773018您能详细说明一下您所说的……我只限于标准的本机SQL查询……是什么意思吗。。。?这一切(准备和执行)都是MySql的本机特性,您不必这样做。请参阅更新的答案。我将它包装到一个存储过程中,以便您简化一些事情。但是,如果您不想手工为所有20列编写语句,您仍然可以享受没有动态SQL的乐趣。谢谢。。。将尝试最新的一个。。。非常感谢你的帮助。你是如何执行的?您看过我提供的SQLFIDLE示例了吗?动态SQL看起来不错。。。。但不幸的是,我只限于标准的本机SQL查询。。。如蒙更多帮助,我们将不胜感激。。谢谢@user1773018您能详细说明一下您所说的……我只限于标准的本机SQL查询……是什么意思吗。。。?这一切(准备和执行)都是MySql的本机特性,您不必这样做。请参阅更新的答案。我将它包装到一个存储过程中,以便您简化一些事情。但是,如果您不想手工为所有20列编写语句,您仍然可以享受没有动态SQL的乐趣。谢谢。。。将尝试最新的一个。。。非常感谢你的帮助。你是如何执行的?您看过我提供的SQLFIDLE示例了吗?