MySQL SELECT仅非空值


264

是否可以执行仅接受NOT NULL值的select语句?

现在我正在使用这个:

SELECT * FROM table

然后,我必须用php循环过滤掉空值。

有没有办法做:

SELECT * (that are NOT NULL) FROM table

现在,当我选择*时,我得到val1,val2,val3,null,val4,val5,null,null等。但是我只想获取结果中不为null的值。没有循环过滤就可以吗?


2
如果某行的某些列具有NULL值而另一些列没有NULL值,那么您要怎么办?
Mark Byers

我只想从不为空的列中获取值,并仅返回不为空的行中的列值。现在我使用循环将它们过滤掉,是否可以不使用循环来进行过滤?
布莱恩·萨蒙

1
@bryan-您的表结构是什么?所有列都具有相同的数据类型吗?
马丁·史密斯,

1
@bryan-那么理想的结果集会是什么样?一列结果集包含所有非空值?如果不使用示例数据和期望的结果来编辑您的问题会有所帮助……
马丁·史密斯

2
@bryan-听起来您的表很可能在列之间有重复的组?(参见用于解释和建议的替代结构维基文章,如果是这样的话en.wikipedia.org/wiki/First_normal_form
马丁·史密斯

Answers:


452

您应该使用IS NOT NULL。(比较操作符=<>两个给定UNKNOWNNULL上表达的任一侧)。

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函数。所以它不应该是END CASE替代ENDSELECT CASE ...一部分吗?
Istiaque Ahmed

对于不太熟练的人,您能解释一下最后的解决方案吗?请问idx ROM中第一个SELECT来自于idx第二SELECT?什么是CASE声明尽力去完成?第二个SELECT实际上做什么?您正在执行内部联接,而不是交叉联接,对吗?
Istiaque Ahmed

我认为这不能回答问题。听起来OP想要选择(我假设是一个特定的)行,但要从结果中排除所有为空的列-此答案要求您指定不允许哪些列为空(这完全是另一个问题)或指定所有列,不适合具有很多列的表
csey18,18-03-13,13

(例如类似的内容SELECT * FROM table WHERE * IS NOT NULL AND primary_key="somevalue"
csey

18

您可以过滤出特定列中包含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等。但是我只想获取结果中不为null的值。没有循环过滤就可以吗?
布莱恩·萨蒙

@bryan-您能解释一下*返回的列吗?可能在您的问题中提供了一些示例数据,因为从上面的注释中还不清楚这是否全部都是一栏。
马丁·史密斯,

现在,*返回行中所有的值。即val1,val2,val3,null,val4,val5,null,null。但我希望它只返回不为null的列值。现在,我使用循环来执行此操作,以在返回结果后过滤掉值。
布莱恩·萨蒙

13
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

2

\!在MySQL中使用命令从外壳grep输出NULL值:

\! mysql -e "SELECT * FROM table WHERE column = 123456\G" | grep -v NULL

.my.cnf在指定您的数据库/用户名/密码的适当位置,它最有效。这样,您只需select要用\! mysql e和括起来即可| grep -v NULL


1

以下查询对我有用

当我设置了列'NULL'的默认值时

select * from table where column IS NOT NULL

当我设置默认值时什么也没有

select * from table where column <>''



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.