SQL Server: как запросить данные во всех строках как объект Json рядом с другими столбцами? - PullRequest
2 голосов
/ 11 июня 2019

У меня есть такие данные: enter image description here

Я хочу запросить такой результат: enter image description here

Вот мойкод

SELECT
     PML_CODE
    ,PML_NAME_ENG
    ,(
        SELECT
              PML_ID
             ,PML_NO
             ,PML_CODE
             ,PML_NAME_ENG
             ,PML_FORMULA
        FROM DSP.PARAMET_LIST AS A WITH(NOLOCK)
        WHERE A.PML_ID = B.PML_ID 
        FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
    ) AS BR_OBJECT
FROM DSP.PARAMET_LIST AS B WITH(NOLOCK)

Мой код работает для того, что я хочу, но я хочу знать, есть ли лучший, более быстрый способ написать этот запрос?

Ответы [ 2 ]

2 голосов
/ 11 июня 2019

Вы можете просто объединить значения. Обязательно приведите целые числа и обработайте значения NULL. Например, если для столбца есть значение NULL, возможны два случая - игнорировать свойство или добавить свойство с помощью null, верно?

Для SQL Server 2016 SP1 + и более поздних версий вы можете использовать FOR JSON. По сути, вы должны получить что-то вроде этого:

DECLARE @DataSource TABLE
(
    [PML_ID] VARCHAR(64)
   ,[PML_NO] INT
   ,[PML_CODE] VARCHAR(3)
   ,[PML_NAME_ENG] NVARCHAR(32)
   ,[PML_FORMULA] VARCHAR(2)
);

INSERT INTO @DataSource ([PML_ID], [PML_NO], [PML_CODE], [PML_NAME_ENG], [PML_FORMULA])
VALUES ('201710260000000050', 1, 'KHR', 'Riel', 01)
      ,('201710260000000051', 2, 'USD', 'Dollar', 02)
      ,('201710260000000052', 3, 'THB', 'Bath', 05);

SELECT [PML_CODE]
      ,[PML_NAME_ENG]
      ,'{"PML_ID":'+ [PML_ID] +',"PML_NO":'+ CAST([PML_NO] AS VARCHAR(12)) +',"PML_CODE":'+ [PML_CODE] +',"PML_NAME_ENG":'+ [PML_NAME_ENG] +',"PML_FORMULA":'+ [PML_FORMULA] +'}' AS [BR_OBJECT]
FROM @DataSource;

-- SQL Server 2016 SP1 and latter
SELECT DS1.[PML_CODE]
      ,DS1.[PML_NAME_ENG]
      ,DS.[BR_OBJECT]
FROM @DataSource DS1
CROSS APPLY
(
    SELECT *
    FROM @DataSource DS2
    WHERE DS1.[PML_CODE] = DS2.[PML_CODE]
      AND DS2.[PML_NAME_ENG] = DS2.[PML_NAME_ENG]
    FOR JSON AUTO
) DS ([BR_OBJECT]);
1 голос
/ 12 июня 2019

В следующий раз, пожалуйста, не публикуйте картинки, а попробуйте создать DDL, заполните его примерами данных и укажите свои собственные попытки и ожидаемый результат. Это облегчит нам понимание и ответ на ваш вопрос.

Вы можете попробовать это так:

DECLARE @tbl TABLE(PML_ID BIGINT, PML_NO INT, PML_CODE VARCHAR(10), PML_NAME_ENG VARCHAR(10), PML_FORMULA VARCHAR(10));
INSERT INTO @tbl VALUES
 (2017102600050,1,'KHR','Riel','01')
,(2017102600051,2,'USD','Dollar','02')
,(2017102600052,3,'THB','Bath','05')

SELECT
     PML_CODE
    ,PML_NAME_ENG
    ,BR_OBJECT
FROM @tbl
CROSS APPLY(
    SELECT
    (
            SELECT
                  PML_ID
                 ,PML_NO
                 ,PML_CODE
                 ,PML_NAME_ENG
                 ,PML_FORMULA
            FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
    )) AS A(BR_OBJECT);

Большая разница в вашем подходе заключается в том, что я использую CROSS APPLY, используя уже существующие столбцы, вместо вызова коррелированного подзапроса .

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