简体   繁体   English

向 mysql json_arrayagg 函数添加条件

[英]add condition to mysql json_arrayagg function

I have a json query that gives me json of a joined table of person and pets:我有一个 json 查询,它给我一个人和宠物的连接表的 json:

SELECT json_object(
  'personId', p.id,
  'pets', json_arrayagg(json_object(
    'petId', pt.id,
    'petName', pt.name
  ))
  )
FROM person p LEFT JOIN pets pt
ON p.id = pt.person_id
GROUP BY p.id;

my issue is that person can have 0 or more pets, and when a person have 0 pets I get list with 1 empty pet, and what I would like to get in that case is empty list.我的问题是那个人可以有 0 只或更多宠物,当一个人有 0 只宠物时,我会得到 1 只空宠物的列表,在这种情况下我想得到的是空列表。

this is what I get:这就是我得到的:

{
  "personId": 1,
  "pets": [
    {
      "petId": null,
      "petName": ""
    }
  ]
}

and I need:我需要:

{
  "personId": 1,
  "pets": []
}

is that possible?那可能吗?

The problem is that LEFT JOIN still returns columns from the table you're joining with, it just sets their values to NULL .问题是LEFT JOIN仍然从您要加入的表中返回列,它只是将它们的值设置为NULL

You can use IF to test COUNT(pt.id) , as this won't count null values.您可以使用IF来测试COUNT(pt.id) ,因为这不会计算空值。

SELECT json_object(
  'personId', p.id,
  'pets', IF(COUNT(pt.id) = 0, JSON_ARRAY(),
             json_arrayagg(json_object(
                'petId', pt.id,
                'petName', pt.name
                )
            ))
  )
FROM person p LEFT JOIN pets pt
ON p.id = pt.person_id
GROUP BY p.id;

Another possibility is to put the aggregation in a correlated subquery and use coalesce() to replace it with an empty array if no rows exist.另一种可能性是将聚合放在相关子查询中,如果不存在行,则使用coalesce()将其替换为空数组。

SELECT json_object('personID', p.id,
                   'pets', coalesce((SELECT json_arrayagg(json_object('petId', t.id,
                                                                      'petName', t.name))
                                            FROM pets t
                                            WHERE t.person_id = p.id),
                                    json_array()))
       FROM person p;

Adding another option:添加另一个选项:

select IFNULL( /*expression of select ...JSON_ARRAYAGG(
                                    JSON_OBJECT(....*/,JSON_ARRAY()) jarrayaggAlias

Cleaner below:下面的清洁剂:

IFNULL( expression, ,JSON_ARRAY()) jarrayaggAlias

Result:结果:

/* { jarrayaggAlias: []  }*/

If you swap alt_value for IFNULL to select [] , then all your results will be stringyfied.如果您将alt_value 换成IFNULL以选择[] ,那么您的所有结果都将被字符串化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM