我有一个包含10个字段的Table
。每个field
或column
都包含Integer
个值。
现在我只需要返回在结果集中有Null
或0
的字段。
答案 0 :(得分:11)
这对我有用。例如:
而不是:
where column_name is null or column_name = 0
这将是:
where COALESCE(column_name,0) = 0
Posted by Jon Gabrielson on December 18, 2002
功能' COALESCE'可以简化使用空值的简化。对于 例如,要将null视为零,您可以使用:select 来自COALESCE(colname,0)>的表中的COALESCE(colname,0) 1;
答案 1 :(得分:3)
使用where column_name is null or column_name = 0
答案 2 :(得分:2)
目前尚不清楚你在问什么。
你能详细说明一下结果集应该是什么样的,你想要返回所有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
)
答案 3 :(得分:0)
我最近不得不用另一种语言制作类似的方法。逻辑是检查记录中的所有“列”是否为“真”,然后才能进行处理。
我绕过它的方式就是这个逻辑:
# 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。
将来,您应该设计数据库表,以便首先不允许/不存储无效记录。
答案 4 :(得分:0)
您是否需要具有NULL或0的列,或者具有NULL或0的列的行,或 all的行列是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;