SQL до JSON - Создать массив Json - PullRequest
1 голос
/ 29 апреля 2020

У меня есть следующие данные:

CREATE TABLE mytable
 (
  ID int,
  Product nvarchar(50),
  Usage nvarchar(255),
 );

INSERT INTO mytable VALUES (99346,'Universal light','Art and Culture');
INSERT INTO mytable VALUES (99346,'Universal light','Health and Care');
INSERT INTO mytable VALUES (99346,'Universal light','Hotel and Wellness');
INSERT INTO mytable VALUES (99346,'Universal light','Education and Science');

И я создал следующий код для получения JSON вывода:

SELECT DISTINCT T1.ID
      ,T1.Product
      ,(SELECT T2.Usage
        FROM mytable T2
        WHERE T1.ID=T2.ID
        FOR JSON PATH) as 'Usage'
FROM mytable T1
FOR JSON PATH

Он выводит следующие результаты:

[
    {
        "ID": 99346,
        "Product": "Universal light",
        "Usage": [
            {
                "Usage": "Art and Culture"
            },
            {
                "Usage": "Health and Care"
            },
            {
                "Usage": "Hotel and Wellness"
            },
            {
                "Usage": "Education and Science"
            }
        ]
    }
]

Я хотел бы получить результаты, как показано ниже, но не могу понять, как изменить синтаксис:

[
    {
        "ID": 99346,
        "Product": "Universal light",
        "Usage": [ "Art and Culture" , "Health and Care" , "Hotel and Wellness" , "Education and Science"
         ]
    }
]

Любая помощь по этому вопросу высоко ценится.

EDIT

Если я использую эти исходные данные, где в конце строки 3 у меня есть лишние '', решение не работает, нет ошибок или предупреждений:

INSERT INTO mytable VALUES (99346,'Universal light','Art and Culture');
INSERT INTO mytable VALUES (99346,'Universal light','Education and Science');
INSERT INTO mytable VALUES (99346,'Universal light','Health and Care ');
INSERT INTO mytable VALUES (99346,'Universal light','Hotel and Wellness');
INSERT INTO mytable VALUES (99346,'Universal light','Offices and Communication');
INSERT INTO mytable VALUES (99346,'Universal light','Presentation and Retail');

У меня есть попытался использовать TRIM, как вы можете видеть ниже:

SELECT Distinct ID
      ,Product
      ,json_query(QUOTENAME(STRING_AGG('"' + STRING_ESCAPE(TRIM(Usage), 'json') + '"', char(44)))) AS 'Usage'
FROM mytable
GROUP BY ID
      ,Product
FOR JSON PATH;

К сожалению, это не работает, и весь массив 'Usage' почему-то игнорируется, смотрите результаты:

[
    {
        "ID": 99346,
        "Product": "Universal light"
    }
]

1 Ответ

1 голос
/ 29 апреля 2020

Вы можете использовать STRING_AGG для построения массива следующим образом:

SELECT  DISTINCT ID
      ,Product
      ,json_query(QUOTENAME(STRING_AGG('"' + STRING_ESCAPE(Usage, 'json') + '"', char(44)))) AS 'Usage'
FROM mytable T1
GROUP BY ID
      ,Product
FOR JSON PATH;

Если вы не используете SQL Sever 2017 или более позднюю версию, вы можете использовать объединение значений, используя XML PATH.

SELECT DISTINCT T1.ID
      ,T1.Product
      ,
       (
         '[' +
          STUFF
          (
                (
                SELECT ',' + '"' + T2.Usage + '"' 
                FROM mytable T2
                WHERE T1.ID=T2.ID
                FOR XML PATH, TYPE
                ).value('.', 'NVARCHAR(MAX)')
                ,1
                ,1
                ,''
            )
          + ']'
       ) as 'Usage'
FROM mytable T1
FOR JSON PATH

Для редактирования используйте:

SELECT Distinct ID
      ,Product
      ,json_query('[' + (STRING_AGG('"' + STRING_ESCAPE(TRIM(Usage), 'json') + '"', char(44))) + ']') AS 'Usage'
FROM mytable
GROUP BY ID
      ,Product
FOR JSON PATH;

Проблема в QUOTENAME ввод ограничен 128 символами и возвращает NULL при добавлении дополнительных записей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...