如何在 SQL Server 中的另一个 STRING_AGG 函数中使用 STRING_AGG 函数

问题描述 投票:0回答:1

我有 3 个表,它们之间有 1-n 关系

CREATE TABLE Province
(
    Id BIGINT PRIMARY KEY,
    Name NVARCHAR(255),
    -- ...
)

CREATE TABLE District
(
    Id BIGINT PRIMARY KEY,
    Name NVARCHAR(255),
    ProvinceId BIGINT REFERENCES [Province](Id)
)

CREATE TABLE Ward
(
    Id BIGINT PRIMARY KEY,
    Name NVARCHAR(255),
    DistrictId BIGINT REFERENCES [District](Id)
)

我想获取一个省份的详细数据,如下所示

{
    "id": 1,
    "province_name": "province name",
    "districts": [
        {
            "id": 1,
            "district_name": "district-1",
            "wards": [1,2,3]
        },
        {
            "id": 2,
            "district_name": "district-2",
            "wards": [4,5]
        }
    ]
}

(1省有很多区,1区有很多区)

这是我使用

STRING_AGG
内置函数实现的

select CONCAT(
    '{"id":"', p.[id], '"',
    ',"province_name":', p.ProvinceName,
    ',"districts":',
    CONCAT(
    '[{',
    STRING_AGG(
        CONCAT('"id":', CAST(po.Id AS VARCHAR(10)),
        ',"name":"', po.[Name],
        '","district_name":[', STRING_AGG(CAST(w.id AS VARCHAR(10)), ','), ']'), '},{'),
    '}]'),
    '}')
from 
    province p
left join 
    district d on d.provinceId = p.id
left join 
    ward w on w.districtId = d.id
where 
    p.id = @id

但是 SQL Server 抛出了这个异常:

无法对包含聚合或子查询的表达式执行聚合函数

我尝试从该网站搜索类似的问题,但找不到预期的结果。

如何实现从3个1-n层获取数据?

sql sql-server
1个回答
0
投票

这是不可能用OP的数据来证明的,因为我们没有任何数据。因此,我使用了一些

sys
对象来演示如何:

  1. 嵌套 JSON 值
  2. 模拟
    JSON_ARRAYAGG
    ,因为它在预览之外不可用。

JSON 嵌套就像 XML 嵌套一样,带有子查询。要将值聚合到数组中,则仍然使用

STRING_AGG
,但是,我们随后需要使用
JSON_QUERY
将其转换为实际的 JSON,而不是文字。这会产生如下所示的结果:

SELECT s.name AS schema_name,
       (SELECT object_id,
              name,
              JSON_QUERY((SELECT CONCAT('[',STRING_AGG(c.column_id,','),']')
                          FROM sys.columns c
                          WHERE c.object_id = t.object_id),'$') AS column_ids
         FROM sys.tables t
         WHERE t.schema_id = s.schema_id
         FOR JSON AUTO) AS tables
FROM sys.schemas s
FOR JSON AUTO;

得到这样的结果:

[
    {
        "schema_name": "dbo"
    },
    {
        "schema_name": "guest"
    },
    {
        "schema_name": "INFORMATION_SCHEMA"
    },
    {
        "schema_name": "sys"
    },
    {
        "schema_name": "fn"
    },
    {
        "schema_name": "sp"
    },
    {
        "schema_name": "t"
    },
    {
        "schema_name": "tbl",
        "tables": [
            {
                "object_id": 389576426,
                "name": "Calendar",
                "column_ids": [
                    1,
                    2,
                    3,
                    4,
                    5,
                    6,
                    7,
                    8
                ]
            },
            {
                "object_id": 1618104805,
                "name": "Clock",
                "column_ids": [
                    1,
                    2,
                    3,
                    4
                ]
            }
        ]
    }
]
© www.soinside.com 2019 - 2024. All rights reserved.