Не включайте фиксированное значение в JSON SQL - PullRequest
0 голосов
/ 13 октября 2019

Я должен сделать JSON из таблицы. Проблема в том, что я должен показывать значения NULL, но скрывать все фиксированные постоянные значения.

Например, у меня есть набор данных #table. В выводе JSON я хочу показать все значения, где Value != 0. Удаление строки (select Value from #table where cn = 'c') as 'c' не вариант. Как я могу это сделать?

create table #table (
   Value int,
   cn nvarchar(1)
)

insert into #table
values
(null, 'a'),
(null, 'b'),
(0, 'c'),
(3, 'd'),
(3, 'f')

select
    (select Value from #table where cn = 'a')  as 'a',
    (select Value from #table where cn = 'b') as 'b', 
    (select Value from #table where cn = 'c') as 'c', 
    (select Value from #table where cn = 'd') as 'd', 
    (select Value from #table where cn = 'f') as 'f'
FOR JSON PATH, INCLUDE_NULL_VALUES 

Ожидаемый результат будет:

[{"a":null,"b":null,"d":3,"f":3}]

Ответы [ 3 ]

1 голос
/ 14 октября 2019

Вы можете сделать это с динамическим SQL. Я использую условное агрегирование для поворота таблицы.

declare @cmd nvarchar(max) = 'select ' + stuff(
    (select  ', max(case cn when ''' + cn + ''' then value end) as ''' + cn +''''
     from #table
     where value <> 0 or value is null
     for xml path(''))
    , 1, 1, '') + ' from #table FOR JSON PATH, INCLUDE_NULL_VALUES';

 --select @cmd;

 exec (@cmd);

Другой вариант основан на типе столбца value (int), поэтому 0.5 невозможно в качестве значения столбца. Преобразуйте исходные значения в десятичные, затем замените невозможные значения на null и удалите десятичную точку и 0 после нее.

select replace(replace(
  (select
    max(case cn when 'a' then value end) 'a',
    max(case cn when 'b' then value end) 'b',
    max(case cn when 'c' then value end) 'c',
    max(case cn when 'd' then value end) 'd',
    max(case cn when 'f' then value end) 'f'
  from( 
   select coalesce(cast(value as decimal), 0.5) value, cn 
   from #table
   where value <> 0 or value is null) t
   FOR JSON PATH)
,'0.5', 'null'), '.0', '');
0 голосов
/ 13 октября 2019

Это не элегантно, но есть одна возможность вручную построить строку:

select concat('[{',
              string_agg(concat('"', cn, '":', coalesce(convert(varchar(255), value), 'null')
                               ), ','
                        ), '}]'
             )
from t
where value <> 0 or value is null
0 голосов
/ 13 октября 2019

Я не думаю, что вы можете изменить количество выбранных столбцов в операторе SQL, но вы можете сделать это:

declare @statement varchar(max) ='
select
    (select Value from #table where cn = ''a'')  as ''a'',
    (select Value from #table where cn = ''b'') as ''b'', 
    --(select Value from #table where cn = ''c'') as ''c'', 
    (select Value from #table where cn = ''d'') as ''d'', 
    (select Value from #table where cn = ''f'') as ''f''
FOR JSON PATH, INCLUDE_NULL_VALUES'


exec sp_sqlexec @statement 

Эффективно построить оператор SQL, чтобы выбрать только те значения, которые не равнына значение, которое вы хотите скрыть.

...