我Table
有 10 个字段。每个field
或column
包含Integer
值。
现在我只需要返回具有Null
或0
在结果集中的字段。
这对我有用。例如:
代替:
where column_name is null or column_name = 0
这将是:
where COALESCE(column_name,0) = 0
张贴者 Jon Gabrielson 于 2002 年 12 月 18 日
函数“COALESCE”可以简化空值的处理。例如,要将 null 视为零,您可以使用: select COALESCE(colname,0) from table where COALESCE(colname,0) > 1;
利用where column_name is null or column_name = 0
不清楚你在问什么。
您能否详细说明结果集的外观,您是否希望返回所有 10 列,但只包括至少有一列包含 NULL 或 0 的行?通过在 WHERE 子句中指定适当的谓词,这很容易做到。
SELECT col0, col1, col2, col3, col4, col5, col6, col7, col8, col9
FROM mytable
WHERE IFNULL(col0,0) = 0
OR IFNULL(col1,0) = 0
OR IFNULL(col2,0) = 0
OR IFNULL(col3,0) = 0
OR IFNULL(col4,0) = 0
OR IFNULL(col5,0) = 0
OR IFNULL(col6,0) = 0
OR IFNULL(col7,0) = 0
OR IFNULL(col8,0) = 0
OR IFNULL(col9,0) = 0
这将返回至少在指定列之一中具有零或 NULL 的所有行。
但是你的问题似乎是在问一些有点不同的东西;您似乎在询问是否根据条件仅返回某些列。结果集中要返回的列由SELECT
关键字后面的表达式列表确定。您不能根据列包含的值动态更改 SELECT 列表中的表达式。
要返回在该列中至少有一行包含 NULL 或零的列的名称,您可以编写这样的查询(这限制为 5 列,可以轻松扩展到 10 列或更多列):
SELECT 'col0' AS col_name FROM mytable WHERE IFNULL(col0,0) = 0
UNION SELECT 'col1' FROM mytable WHERE IFNULL(col1,0) = 0
UNION SELECT 'col2' FROM mytable WHERE IFNULL(col2,0) = 0
UNION SELECT 'col3' FROM mytable WHERE IFNULL(col3,0) = 0
UNION SELECT 'col4' FROM mytable WHERE IFNULL(col4,0) = 0
(该查询将对表进行一些认真的扫描。如果索引可用,则可以重写谓词以允许索引范围扫描。)
这是一种将 column_names 放在一行中的方法。(其中一列中的 NULL 表示该列不包含任何零或 NULL。)
SELECT (SELECT 'col0' FROM mytable WHERE IFNULL(col0,0)=0 LIMIT 1) AS col0
, (SELECT 'col1' FROM mytable WHERE IFNULL(col1,0)=0 LIMIT 1) AS col1
, (SELECT 'col2' FROM mytable WHERE IFNULL(col2,0)=0 LIMIT 1) AS col2
, (SELECT 'col3' FROM mytable WHERE IFNULL(col3,0)=0 LIMIT 1) AS col3
, (SELECT 'col4' FROM mytable WHERE IFNULL(col4,0)=0 LIMIT 1) AS col4
但是对表进行一次扫描会快得多:
SELECT IF(c0>0,'col0',NULL)
, IF(c1>0,'col1',NULL)
, IF(c2>0,'col2',NULL)
, IF(c3>0,'col3',NULL)
, IF(c4>0,'col4',NULL)
FROM ( SELECT SUM(IF(IFNULL(col0,0)=0,1,0)) AS c0
, SUM(IF(IFNULL(col1,0)=0,1,0)) AS c1
, SUM(IF(IFNULL(col2,0)=0,1,0)) AS c2
, SUM(IF(IFNULL(col3,0)=0,1,0)) AS c3
, SUM(IF(IFNULL(col3,0)=0,1,0)) AS c4
FROM mytable
)
我最近不得不用另一种语言制作类似的方法。逻辑是在处理记录之前检查记录中的所有“列”是否为“真”。
我解决它的方法是使用以下逻辑:
# loop through the records
for ($i=0; $i<count($records); $i++) {
# in each record, if any column is 0 or null we will disgard it
# this boolean will tell us if we can keep the record or not
# default value is 'true', this gives it a chance to survive
$keepit = true;
# loop through each column
for ($j=0; $j<count($records[$i]); $j++) {
# add your boolean condition (true=go ahead, false=cant go ahead)
$goahead = (!is_null($records[$i][$j]) && $records[$i][$j] != 0);
# convert the boolean to a 0 or 1,
# find the minimum number in a record
# (so if any field in a record is false i.e. 0 or null, dont use the record)
$keepit = min(+$goahead, +$keepit);
}#end of col loop
if ($keepit) {
# keep the record
array_push($anotherArray, $records[$i]);
}
}
我已经用 PHP 为你写了这个。它在 MySQL 中也可能是可行的,但我建议您获取所有记录,在 PHP 中处理它们,然后将它们发送回 MySQL。
将来,您应该设计您的数据库表,以便首先不允许/不存储无效记录。
您是否需要具有 NULL 或 0 的列,或者具有 NULL 或 0列的行,或者所有列都为 NULL 或 0 的行?
但我怀疑在精心设计的表中是否会有 10 个等效列,因此您可能需要重新设计数据模型——在另一个表中创建列行,并将两个表连接在一起。
你可能有这样的事情:
CREATE TABLE a(a_id int primary key, b0 int, b1 int, b2 int, ..., b9 int );
但是你想要这个:
CREATE TABLE a( a_id int primary key );
CREATE TABLE b( b_id int primary key );
INSERT INTO b (b_id) values (0), (1), ..., (9);
CREATE TABLE ab (
a_id int, b_id int,
v int not null, -- this would be the value of b0, b1, ...
foreign key (a_id) references a(a_id),
foreign key (b_id) references b(b_id),
primary key(a_id, b_id)
);
然后你可以写如下内容:
SELECT * FROM a, b -- cross join to get all possible combinations
WHERE (a_id, b_id) NOT IN (
-- then remove the ones that have a value
SELECT a_id, b_id FROM a JOIN ab ON a.id = ab.a_id JOIN b ON ab.a_id
WHERE ab.v <> 0);
如果在运行它之前删除所有 0 行,则最后一行是不必要的:
DELETE FROM ab WHERE v = 0;