选择所有 3 列同时不为空的位置(Laravel 查询生成器)

Posted

技术标签:

【中文标题】选择所有 3 列同时不为空的位置(Laravel 查询生成器)【英文标题】:Select where all 3 columns are not null at the same time (Laravel Query Builder) 【发布时间】:2019-07-13 11:36:51 【问题描述】:

articles DB 表(和Article 模型)具有(以及其他)这 3 列:

col_1 col_2 col_3

如何选择这3列NULL同时的所有文章?

因此,如果 col_1 = NULLcol_2 = NULLcol_3 = NULL - 不要选择(包括)这些文章。但是如果这些列中的一个或多个不是NULL - 然后选择(包括)它。

查询生成器如下所示:

Article::select('articles.*')-> ... ->get();

当然,不是...,而是检查所有这 3 列是否为空同时

我知道这是错误的:

Article::select('articles.*')
       ->whereNotNull('col_1')
       ->whereNotNull('col_2')
       ->whereNotNull('col_3')
       ->get();

...因为它不会选择(包括)例如一篇为 NULL(col_1)而其余(col_2col_3)不为 NULL 的文章。

------------------ 更新:------------------

澄清一下:我想选择(包括)col_1col_2col_3没有或一两个NULL,但 不是如果三个都是 NULL

【问题讨论】:

澄清一下,您想要所有 3 列中所有不为空的文章?因此,如果这 3 列中的任何一个不为空,则不应包含该记录?如果是这样,我相信您拥有的代码应该可以工作。你的最后一句话真的让我失望,因为它与你之前所说的你想要发生的事情相矛盾。 @user3158900 如果这 3 列中的任何一个不为空,则应包含该记录!只有当所有 3 个都为 NULL 时,它才应该包含。 您的查询看起来正确;链接->whereNoNull() 子句将使用AND 逻辑,因此您的查询将转换为SELECT * FROM articles WHERE col_1 IS NOT NULL AND col_2 IS NOT NULL AND col_3 IS NOT NULL;。为什么这不起作用?您能否将此查询的结果与在您的数据库程序(mysqlWorkBench 等)中运行原始查询进行比较? @TimLewis 嗯,这会选择(包括)哪些文章,例如,col_1 不是 NULL,但是col_2 b> NULL? 不;您的查询是说只包括所有 3 列都不为空的文章。如果 col_1、col_2 或 col_3 中的任何一个是null,则不会包含在内。你需要whereNotNull(),与 2 个orWhereNotNull() 链接...我想。 【参考方案1】:

您要查找的查询是:

SELECT
    *
FROM
    `articles`
WHERE
    `col_1` IS NOT NULL
    OR `col_2` IS NOT NULL
    OR `col_3` IS NOT NULL
;

在 Laravel 中,这将导致以下结果:

Article::orWhereNotNull('col_1') 
   ->orWhereNotNull('col_2')
   ->orWhereNotNull('col_3')
   ->get();

如果我没记错的话,select('articles.*') 中的完全相同的选择是由 Eloquent 完成的。也许第一个orWhereNotNull应该是whereNotNull,但你必须自己找出来。

【讨论】:

【参考方案2】:

您正在寻找的查询生成器是:

$articles = Article::where(function($q)
   return $q->whereNotNull('col_1')
       ->orWhereNotNull('col_2')
       ->orWhereNotNull('col_3');
)->get();

在闭包中添加 or 子句的原因是to group them。因此,如果将来您想添加另一个类似的位置:

SELECT
    *
FROM
    `articles`
WHERE 
    (`col_1` IS NOT NULL OR `col_2` IS NOT NULL OR `col_3` IS NOT NULL)
    AND
    `type` = 1
;

你一个直接加:

$articles = Article::where(function($q)
   return $q->whereNotNull('col_1')
       ->orWhereNotNull('col_2')
       ->orWhereNotNull('col_3');
)
->where('type', 1)->get();

如果你这样做:

$articles = Article::orWhereNotNull('col_1') 
   ->orWhereNotNull('col_2')
   ->orWhereNotNull('col_3')
   ->where('type', 1)
   ->get();

下面的查询不是你需要的:

SELECT
    *
FROM
    `articles`
WHERE 
    `col_1` IS NOT NULL 
    OR `col_2` IS NOT NULL 
    OR `col_3` IS NOT NULL
    AND `type` = 1
;

【讨论】:

【参考方案3】:

一个更简单的方法是

Article::select('articles.*')
   ->whereNotNull(['col_1','col_2','col_3'])
   ->get();

【讨论】:

以上是关于选择所有 3 列同时不为空的位置(Laravel 查询生成器)的主要内容,如果未能解决你的问题,请参考以下文章

选择 mongoid 中不为空或为空的位置

选择性过滤列值不为空的行 PostgreSQL

按列分组,优先选择另一列不为空的行

Firestore 选择不为空的位置

仅在其不为空的情况下更新 [重复]

选择字段不为空的数据