Mysql 从表中仅选择具有null/empty值的列
我有一个看起来像这样的数据集,但是列继续作为data4、data5到data20Mysql 从表中仅选择具有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
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示例了吗?