返回一行中包含NULL或0值的列

时间:2012-07-26 22:17:15

标签: mysql sql select null

我有一个包含10个字段的Table。每个fieldcolumn都包含Integer个值。

现在我只需要返回在结果集中有Null0的字段。

5 个答案:

答案 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;