嵌套FOR JSON PATH时根级别的多个属性?

时间:2018-01-09 20:45:02

标签: json sql-server

正在运行SQL Server 2016。考虑下面的示例。只要为每个查询提供别名,嵌套FOR JSON PATH就很容易。在我的情况下,我希望很多(但不是全部)属性属于根 - 即没有别名!

使用不需要的别名a

DECLARE @SomeID int = 1

SELECT
    (SELECT TOP 1 ID, A1, A2 FROM A WHERE ID = @SomeID
        FOR JSON PATH) AS 'a', -- Unwanted!
    (SELECT TOP 1 ID, B1, B2 FROM B WHERE ID = @SomeID
        FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) AS 'b'
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER

如果删除别名,则在运行查询时会出现此错误:

  

不能使用没有名称或别名的列表达式和数据源   使用FOR JSON子句格式化为JSON文本。为未命名的别名添加别名   列或表。

没有别名。重复查询:

SELECT
    -- Wanted! But tedious for more complex queries...
    (SELECT TOP 1 ID FROM A WHERE ID = @SomeID) AS 'id',
    (SELECT TOP 1 A1 FROM A WHERE ID = @SomeID) AS 'a1',
    (SELECT TOP 1 A2 FROM A WHERE ID = @SomeID) AS 'a2',
    (SELECT TOP 1 ID, B1, B2 FROM B WHERE ID = @SomeID
        FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) AS 'b'
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER

后者产生右JSON。但是,在我的复杂数据库中,我不能重复这样的陈述。因此,我需要一个更好的构造来在根上放置许多属性 - 没有别名。 如何实现这一目标?

(完整性。下面创建样本表的脚本。)

CREATE TABLE A(ID int, A1 int, A2 int)
GO

INSERT INTO A(ID, A1, A2)
    SELECT 1, 0, 0
    UNION
    SELECT 1, 1, 1

CREATE TABLE B(ID int, B1 int, B2 int)
GO

INSERT INTO B(ID, B1, B2)
    SELECT 1, 100, 100
    UNION
    SELECT 1, 101, 101

1 个答案:

答案 0 :(得分:1)

这应该产生你所追求的JSON,而不重复查询。

select 
top 1
    id, 
    a1, 
    a2,
    (SELECT TOP 1 ID, B1, B2 FROM @B WHERE ID = @SomeID FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) AS 'b'
from a  
where id = @someid
for json path, without_array_wrapper