MySQL仅选择非空值

320

能否仅选择非NULL值的select语句?

我现在使用的是这个:

SELECT * FROM table

然后我需要使用PHP循环过滤掉空值。

有没有一种方法可以实现:

SELECT * (that are NOT NULL) FROM table

我现在使用select *语句,结果包含val1,val2,val3,null,val4,val5,null,null等等... 但是我只想得到结果中不为null的值。有没有可能在不使用循环过滤的情况下实现这一点?


2
如果有一行数据中的某些列具有 NULL 值,而其他列具有非空值,你希望发生什么? - Mark Byers
1
@bryan - 你的表结构是什么?所有列都有相同的数据类型吗? - Martin Smith
1
@bryan - 那么你的理想结果集会是什么样子呢?一个包含所有非空值的单列结果集吗?如果不是,编辑你的问题并提供示例数据和期望的结果将会很有帮助... - Martin Smith
2
@bryan - 听起来你的表格可能在列之间有重复的组?(如果是这种情况,请参阅维基百科文章以了解说明和建议的替代结构http://en.wikipedia.org/wiki/First_normal_form) - Martin Smith
谢谢,我会去研究一下的。 - bryan sammon
显示剩余5条评论
12个回答

529
你应该使用IS NOT NULL。(比较运算符=<> 在表达式的任一侧为NULL 时都会返回UNKNOWN。)
SELECT * 
FROM table 
WHERE YourColumn IS NOT NULL;

完整性起见,我将提到在MySQL中,您也可以否定空安全相等运算符,但这不是标准SQL。

SELECT *
FROM table 
WHERE NOT (YourColumn <=> NULL);

根据评论修改后的内容。看起来您的表可能不符合第一范式,如果是这样,改变结构可能会使您的任务更容易。还有其他几种方法可以实现...

SELECT val1 AS val
FROM  your_table
WHERE val1 IS NOT NULL
UNION ALL
SELECT val2 
FROM  your_table
WHERE val2 IS NOT NULL
/*And so on for all your columns*/

上述方法的缺点在于它会为每一列扫描表格多次。下面的方法可能可以避免这种情况,但我还没有在MySQL中进行测试。
SELECT CASE idx
         WHEN 1 THEN val1
         WHEN 2 THEN val2
       END AS val
FROM   your_table
        /*CROSS JOIN*/
       JOIN (SELECT 1 AS idx
                   UNION ALL
                   SELECT 2) t
HAVING val IS NOT NULL  /*Can reference alias in Having in MySQL*/

2
非常感谢,它帮了我大忙 :) - DfrDkn
在上一个方法中,您使用了 CASE 语句而不是 CASE 函数。因此,在 SELECT CASE ... 部分中,应该使用 END CASE 而不是 END,对吗? - Istiaque Ahmed
对于不太熟悉的人,你能解释一下最后的解决方案吗?第一个SELECT中的idx是否来自第二个SELECT中的idxCASE语句试图实现什么目标?第二个SELECT实际上是做什么的?而且你正在进行内连接,而不是交叉连接,对吗? - Istiaque Ahmed
1
我认为这并没有回答问题。听起来像是 OP 想要选择(我假设是一个特定的)行,但从结果中排除所有列为空的内容 - 这个答案要求您指定哪些列不允许为空(这是完全不同的问题),或者指定所有列,这对于具有许多列的表格来说是不合适的。 - csey
我认为这更多是因为它解决了他的问题,而不是回答了他的问题,而且听起来他想要的并不能像上面那样简洁地实现。 - csey
显示剩余3条评论

24
您可以过滤掉特定列中包含 NULL 值的行:
SELECT col1, col2, ..., coln
FROM yourtable
WHERE somecolumn IS NOT NULL

如果你想过滤掉任何列中含有空值的行,请尝试这样做:

SELECT col1, col2, ..., coln
FROM yourtable
WHERE col1 IS NOT NULL
AND col2 IS NOT NULL
-- ...
AND coln IS NOT NULL
更新:根据您的评论,也许您想要这个?
SELECT * FROM
(
    SELECT col1 AS col FROM yourtable
    UNION
    SELECT col2 AS col FROM yourtable
    UNION
    -- ...
    UNION
    SELECT coln AS col FROM yourtable
) T1
WHERE col IS NOT NULL

我同意 Martin 的观点,如果你需要这样做,那么你可能应该更改你的数据库设计。


我不确定我是否解释得足够清楚,但我会再尝试一下。现在当我选择*时,我会得到val1、val2、val3、null、val4、val5、null、null等值... 但我只想在结果中获取非空的值。这是否可能而不使用循环进行过滤? - bryan sammon
@bryan - 你能解释一下 * 返回的列是什么吗?或者在你的问题中提供一些示例数据,因为从你上面的评论中并不清楚这是否是一个列。 - Martin Smith
现在,*返回行中的所有值。即val1,val2,val3,null,val4,val5,null,null。但我希望它只返回不为null的列值。现在,我使用循环来过滤掉结果返回后的值。 - bryan sammon

15
Select * from your_table 
WHERE col1 and col2 and col3 and col4 and col5 IS NOT NULL;

这种方法唯一的缺点是你只能比较5列,之后结果总是false,所以我只比较那些可以为NULL的字段。


8

我找到了这个解决方案:

这个查询可以选择每列的最后一个非空值。

例如:


如果你有一个表:

id|title|body
1 |t1   |b1
2 |NULL |b2
3 |t3   |NULL

你将获得:

title|body
t3   |b2

查询


SELECT DISTINCT (

  SELECT title
  FROM test
  WHERE title IS NOT NULL 
  ORDER BY id DESC 
  LIMIT 1
) title, (

  SELECT body
  FROM test
  WHERE body IS NOT NULL 
  ORDER BY id DESC 
  LIMIT 1
) body
FROM test

我希望能为您提供帮助。


GROUP_CONCAT(body) AS body - Ravindra Singh

4

以下查询对我有效:

当我将列的默认值设置为“NULL”时

select * from table where column IS NOT NULL

当我没有设置默认值时

select * from table where column <>''

2
MYSQL IS NOT NULL的使用方法,包括JOIN和SELECT、INSERT INTO、DELETE以及逻辑运算符LIKE OR、NOT。最初的回答请参考:https://www.tutsmake.com/mysql-where-is-not-null-with-examples/
Using IS NOT NULL On Join Conditions

 SELECT * FROM users 
 LEFT JOIN posts ON post.user_id = users.id 
 WHERE user_id IS NOT NULL;

 Using IS NOT NULL With AND Logical Operator

 SELECT * FROM users 
 WHERE email_address IS NOT NULL 
 AND mobile_number IS NOT NULL;

Using IS NOT NULL With OR Logical Operator

 SELECT * FROM users 
 WHERE email_address IS NOT NULL 
 OR mobile_number IS NOT NULL;

2
我使用MySQL中的\!命令来从shell中搜索NULL值:
\! mysql -e "SELECT * FROM table WHERE column = 123456\G" | grep -v NULL

最好使用正确的.my.cnf文件,其中指定了您的数据库/用户名/密码。这样,您只需在select周围加上\! mysql e| grep -v NULL就可以了。


1

请在您的查询中使用 NOT NULL ,例如下面这样。

SELECT * 
FROM table
WHERE col IS NOT NULL;

0
你甚至不需要使用星号来获取表格字段。

-3
SELECT duration,id FROM `tickets` WHERE duration !=""

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接