SQL Server FOR JSON路径,如果为空,则排除特定字段

SQL Server FOR JSON路径,如果为空,则排除特定字段,sql,json,sql-server,sql-server-json,Sql,Json,Sql Server,Sql Server Json,我有这样的数据表 Id | Name | Phone | OtherField ----+---------+--------+----------- 1 | ABC | 12344 | NULL 2 | XYZ | NULL | NULL [ { "ID":1, "Name":"ABC", "Phone":[

我有这样的数据表

Id  |  Name   | Phone  | OtherField 
----+---------+--------+-----------
 1  | ABC     | 12344  | NULL
 2  | XYZ     | NULL   | NULL
[
    {
      "ID":1,
      "Name":"ABC",
      "Phone":[
               {"Home":"12344"}
             ],
       "OtherFields":NULL
     },
    {
     "ID":1,
     "Name":"ABC",
     "OtherFields":NULL
    }
]
我想要一个SQL查询来像这样转换它

Id  |  Name   | Phone  | OtherField 
----+---------+--------+-----------
 1  | ABC     | 12344  | NULL
 2  | XYZ     | NULL   | NULL
[
    {
      "ID":1,
      "Name":"ABC",
      "Phone":[
               {"Home":"12344"}
             ],
       "OtherFields":NULL
     },
    {
     "ID":1,
     "Name":"ABC",
     "OtherFields":NULL
    }
]
我知道
包含空值
它包含所有空字段。
我想包括除电话以外的所有其他字段。

我已编辑了我的答案,因为您已更改了原始请求

我不相信你可以有两种方法,保留一些空值而不是其他。目前我能想到的最好的方法是在必须保留的列上使用
ISNULL

例如:

DECLARE @Table TABLE ( Id INT, Name VARCHAR(10), Phone VARCHAR(10), OtherField VARCHAR(10) );
INSERT INTO @Table ( Id, Name, Phone ) VALUES
    ( 1, 'ABC', '12344' ), ( 2, 'XYZ', NULL );

SELECT 
    Id, Name, 
    JSON_QUERY ( CASE
        WHEN t.Phone IS NOT NULL THEN x.Phone
        ELSE NULL
    END ) AS Phone,
    ISNULL( OtherField, '' ) AS OtherFields
FROM @Table t
CROSS APPLY (
    SELECT ( SELECT Phone AS Home FOR JSON PATH ) AS Phone
) x
    FOR JSON PATH;
返回

[{
    "Id": 1,
    "Name": "ABC",
    "Phone": [{
        "Home": "12344"
    }],
    "OtherFields": ""
}, {
    "Id": 2,
    "Name": "XYZ",
    "OtherFields": ""
}]

我已经编辑了我的答案,因为您已经更改了原始请求

我不相信你可以有两种方法,保留一些空值而不是其他。目前我能想到的最好的方法是在必须保留的列上使用
ISNULL

例如:

DECLARE @Table TABLE ( Id INT, Name VARCHAR(10), Phone VARCHAR(10), OtherField VARCHAR(10) );
INSERT INTO @Table ( Id, Name, Phone ) VALUES
    ( 1, 'ABC', '12344' ), ( 2, 'XYZ', NULL );

SELECT 
    Id, Name, 
    JSON_QUERY ( CASE
        WHEN t.Phone IS NOT NULL THEN x.Phone
        ELSE NULL
    END ) AS Phone,
    ISNULL( OtherField, '' ) AS OtherFields
FROM @Table t
CROSS APPLY (
    SELECT ( SELECT Phone AS Home FOR JSON PATH ) AS Phone
) x
    FOR JSON PATH;
返回

[{
    "Id": 1,
    "Name": "ABC",
    "Phone": [{
        "Home": "12344"
    }],
    "OtherFields": ""
}, {
    "Id": 2,
    "Name": "XYZ",
    "OtherFields": ""
}]

更新:

原始问题经过编辑,我不认为您可以使用JSON的单个
INCLUDE_NULL_VALUES
生成预期的ouptut,因为现在表中有多个列具有
NULL
值(
OtherField

作为一种可能的解决方案,您可以尝试一种混合方法(使用JSON的
字符串_AGG()
)来构建最终的JSON输出,并将所有列的
值保持为NULL,除了
电话

CREATE TABLE Data (
   Id int, 
   Name varchar(100), 
   Phone varchar(100),
   OtherField varchar(1)
);
INSERT INTO Data (Id, Name, Phone, OtherField) 
VALUES
    (1, 'ABC', '12344', NULL), 
    (2, 'ABC', NULL, NULL),
    (3, 'ABC', NULL, NULL)
声明:

SELECT CONCAT(
   '[',
   (
   SELECT STRING_AGG(j.Json, ',')
   FROM Data d
   CROSS APPLY (
      SELECT CASE
         WHEN Phone IS NOT NULL THEN (
            SELECT Id, Name, (SELECT Phone AS Home FOR JSON PATH) AS Phone, OtherField 
            FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
         )
         ELSE (
            SELECT Id, Name, OtherField
            FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
         )
      END
   ) j (Json)
   ),
   ']'
)   
SELECT 
   Id, 
   Name, 
   JSON_QUERY(CASE WHEN Phone IS NOT NULL THEN (SELECT Phone AS Home FOR JSON PATH) END) AS Phone
FROM Data
FOR JSON PATH
结果:

[
   {"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}],"OtherField":null},
   {"Id":2,"Name":"ABC","OtherField":null},
   {"Id":3,"Name":"ABC","OtherField":null}
]
[
   {"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}]},
   {"Id":2,"Name":"ABC"}
]
原始答案:

您可以尝试以下语句:

表:

CREATE TABLE Data (
   Id int, 
   Name varchar(100), 
   Phone varchar(100) 
);
INSERT INTO Data (Id, Name, Phone) 
VALUES
    (1, 'ABC', '12344'), 
    (2, 'ABC', NULL )
声明:

SELECT CONCAT(
   '[',
   (
   SELECT STRING_AGG(j.Json, ',')
   FROM Data d
   CROSS APPLY (
      SELECT CASE
         WHEN Phone IS NOT NULL THEN (
            SELECT Id, Name, (SELECT Phone AS Home FOR JSON PATH) AS Phone, OtherField 
            FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
         )
         ELSE (
            SELECT Id, Name, OtherField
            FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
         )
      END
   ) j (Json)
   ),
   ']'
)   
SELECT 
   Id, 
   Name, 
   JSON_QUERY(CASE WHEN Phone IS NOT NULL THEN (SELECT Phone AS Home FOR JSON PATH) END) AS Phone
FROM Data
FOR JSON PATH
结果:

[
   {"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}],"OtherField":null},
   {"Id":2,"Name":"ABC","OtherField":null},
   {"Id":3,"Name":"ABC","OtherField":null}
]
[
   {"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}]},
   {"Id":2,"Name":"ABC"}
]

更新:

原始问题经过编辑,我不认为您可以使用JSON的单个
INCLUDE_NULL_VALUES
生成预期的ouptut,因为现在表中有多个列具有
NULL
值(
OtherField

作为一种可能的解决方案,您可以尝试一种混合方法(使用JSON的
字符串_AGG()
)来构建最终的JSON输出,并将所有列的
值保持为NULL,除了
电话

CREATE TABLE Data (
   Id int, 
   Name varchar(100), 
   Phone varchar(100),
   OtherField varchar(1)
);
INSERT INTO Data (Id, Name, Phone, OtherField) 
VALUES
    (1, 'ABC', '12344', NULL), 
    (2, 'ABC', NULL, NULL),
    (3, 'ABC', NULL, NULL)
声明:

SELECT CONCAT(
   '[',
   (
   SELECT STRING_AGG(j.Json, ',')
   FROM Data d
   CROSS APPLY (
      SELECT CASE
         WHEN Phone IS NOT NULL THEN (
            SELECT Id, Name, (SELECT Phone AS Home FOR JSON PATH) AS Phone, OtherField 
            FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
         )
         ELSE (
            SELECT Id, Name, OtherField
            FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
         )
      END
   ) j (Json)
   ),
   ']'
)   
SELECT 
   Id, 
   Name, 
   JSON_QUERY(CASE WHEN Phone IS NOT NULL THEN (SELECT Phone AS Home FOR JSON PATH) END) AS Phone
FROM Data
FOR JSON PATH
结果:

[
   {"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}],"OtherField":null},
   {"Id":2,"Name":"ABC","OtherField":null},
   {"Id":3,"Name":"ABC","OtherField":null}
]
[
   {"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}]},
   {"Id":2,"Name":"ABC"}
]
原始答案:

您可以尝试以下语句:

表:

CREATE TABLE Data (
   Id int, 
   Name varchar(100), 
   Phone varchar(100) 
);
INSERT INTO Data (Id, Name, Phone) 
VALUES
    (1, 'ABC', '12344'), 
    (2, 'ABC', NULL )
声明:

SELECT CONCAT(
   '[',
   (
   SELECT STRING_AGG(j.Json, ',')
   FROM Data d
   CROSS APPLY (
      SELECT CASE
         WHEN Phone IS NOT NULL THEN (
            SELECT Id, Name, (SELECT Phone AS Home FOR JSON PATH) AS Phone, OtherField 
            FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
         )
         ELSE (
            SELECT Id, Name, OtherField
            FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
         )
      END
   ) j (Json)
   ),
   ']'
)   
SELECT 
   Id, 
   Name, 
   JSON_QUERY(CASE WHEN Phone IS NOT NULL THEN (SELECT Phone AS Home FOR JSON PATH) END) AS Phone
FROM Data
FOR JSON PATH
结果:

[
   {"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}],"OtherField":null},
   {"Id":2,"Name":"ABC","OtherField":null},
   {"Id":3,"Name":"ABC","OtherField":null}
]
[
   {"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}]},
   {"Id":2,"Name":"ABC"}
]

然后你的json格式是错误的,有错误的结果,然后你的json格式是错误的,有错误的结果,但我想从第二个对象中删除phone,像这样[{“Id”:1,“Name”:“ABC”,“phone”:[{“Home”:“12344”}],“OtherField”:null},{“Id”:2,“Name”:“ABC”,“OtherField”:null}]可以,但我想从第二个对象中删除phone,像这样[{“Id”:1,“Name”:“ABC”,“Phone”:[{“Home”:“12344”}],“OtherField”:null},{“Id”:2,“Name”:“ABC”,“OtherField”:null}]