如何从MySQL CONCAT和GROUP_CONCAT中跳过空值

如何从MySQL CONCAT和GROUP_CONCAT中跳过空值,mysql,Mysql,我有一个以JSON字符串形式返回产品名称和图像数组的查询。但是,当没有图像附加到产品时,我希望此查询为images属性返回一个空数组 当前,当找不到产品图像时,它会返回以下内容: { "name": "Product Name", "images": [{"id": null, "slug": null}]} 我试图将IF条件添加到CONCAT方法中,但它返回相同的响应 SELECT p.name, CONCAT('[', IF(i.id = NULL,

我有一个以JSON字符串形式返回产品名称和图像数组的查询。但是,当没有图像附加到产品时,我希望此查询为images属性返回一个空数组

当前,当找不到产品图像时,它会返回以下内容:

{ "name": "Product Name", "images": [{"id": null, "slug": null}]}
我试图将IF条件添加到CONCAT方法中,但它返回相同的响应

SELECT p.name,
CONCAT('[',
          IF(i.id = NULL,
            '',
            GROUP_CONCAT(DISTINCT (
              JSON_OBJECT(
                'id', i.id, 
                'slug', i.slug
              )
            ))
          ),
       ']') AS images
FROM products AS p
        LEFT JOIN _product_images AS pi ON pi.pId = p.id
        LEFT JOIN images AS i ON i.id = pi.iId
WHERE p.id = 4;
谢谢大家!

您应该使用IS NULL来检查空值:

作为旁注,DISTINCT不是一个函数,您不应该这样使用它,因此我删除了您使用的函数括号。

您应该使用is NULL检查空值:

作为旁注,DISTINCT不是一个函数,您不应该这样使用它,因此我删除了您使用的函数括号。

IFi.id=NULL。。。返回NULL,对于任何具有i.id的值,甚至返回NULL,这是一个伪值

如果i.id为NULL,则要使用

发件人:

不能使用算术比较运算符,例如=,选择1=NULL,1 NULL,1NULL; +-----+------+-----+-----+ |1=NULL | 1 NULL | 1NULL | +-----+------+-----+-----+ |空|空|空|空| +-----+------+-----+-----+ 如果i.id=NULL。。。返回NULL,对于任何具有i.id的值,甚至返回NULL,这是一个伪值

如果i.id为NULL,则要使用

发件人:

不能使用算术比较运算符,例如=,选择1=NULL,1 NULL,1NULL; +-----+------+-----+-----+ |1=NULL | 1 NULL | 1NULL | +-----+------+-----+-----+ |空|空|空|空| +-----+------+-----+-----+ 正如其他人提到的,i.id=NULL将始终计算为NULL。但是您的方法不必要地复杂,并且会在严格配置的服务器上引发错误。在db fiddle上,我得到以下错误:

_GROUP_FUNC_和_字段的ER_MIX_:在没有分组依据的聚合查询中, 选择列表的表达式2包含未聚合的列 “测试i.id”;这与sql\u mode=only\u full\u group\u by不兼容

因此,需要在GROUP_CONCAT函数中检查i.id是否为NULL:

SELECT p.name,
CONCAT('[',
  GROUP_CONCAT(DISTINCT (
    IF (i.id IS NULL, '',
      JSON_OBJECT(
        'id', i.id, 
        'slug', i.slug
       )
    )
   )),
']') AS images
FROM products AS p
        LEFT JOIN _product_images AS pi ON pi.pId = p.id
        LEFT JOIN images AS i ON i.id = pi.iId
WHERE p.id = 4
但是,当使用内部联接时,可以避免检查。但是内部连接也会忽略products表中的数据,所以我会在相关子查询中进行连接。最后,您可以使用JSON_ArrayAg生成JSON数组

正如其他人提到的,i.id=NULL将始终计算为NULL。但是您的方法不必要地复杂,并且会在严格配置的服务器上引发错误。在db fiddle上,我得到以下错误:

_GROUP_FUNC_和_字段的ER_MIX_:在没有分组依据的聚合查询中, 选择列表的表达式2包含未聚合的列 “测试i.id”;这与sql\u mode=only\u full\u group\u by不兼容

因此,需要在GROUP_CONCAT函数中检查i.id是否为NULL:

SELECT p.name,
CONCAT('[',
  GROUP_CONCAT(DISTINCT (
    IF (i.id IS NULL, '',
      JSON_OBJECT(
        'id', i.id, 
        'slug', i.slug
       )
    )
   )),
']') AS images
FROM products AS p
        LEFT JOIN _product_images AS pi ON pi.pId = p.id
        LEFT JOIN images AS i ON i.id = pi.iId
WHERE p.id = 4
但是,当使用内部联接时,可以避免检查。但是内部连接也会忽略products表中的数据,所以我会在相关子查询中进行连接。最后,您可以使用JSON_ArrayAg生成JSON数组


id怎么可能为空?@草莓有一个左join,但在这种情况下GC不会忽略空值吗?GC从JSON_对象获取一个有效的JSON。id怎么可能为空?@草莓有一个左join,但GC不会忽略空值吗?GC从JSON_对象获取一个有效的JSON。您正在尝试访问组外的i.id函数,但它不在GROUP BY或WHERE子句中。您试图在GROUP BY或WHERE子句中的i.id之外访问它。
SELECT p.name, COALESCE((
  SELECT JSON_ARRAYAGG(JSON_OBJECT(
    'id', i.id, 
    'slug', i.slug
  ))
  FROM _product_images AS pi 
  JOIN images AS i ON i.id = pi.iId
  WHERE pi.pId = p.id
), JSON_ARRAY()) AS images
FROM products AS p
#WHERE p.id = 4;