不要在 JSON SQL 中包含固定值
Do not include fixed value in JSON SQL
我必须从 table 制作 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}]
我认为您不能改变 SQL 语句中 selected 列的数量,但您可以这样做:
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 语句,仅 select 那些不等于您要隐藏的值的值。
这并不优雅,但一种可能是手动构建字符串:
select concat('[{',
string_agg(concat('"', cn, '":', coalesce(convert(varchar(255), value), 'null')
), ','
), '}]'
)
from t
where value <> 0 or value is null
您可以使用动态 sql 来完成。我使用条件聚合来转换 table.
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', '');
我必须从 table 制作 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}]
我认为您不能改变 SQL 语句中 selected 列的数量,但您可以这样做:
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 语句,仅 select 那些不等于您要隐藏的值的值。
这并不优雅,但一种可能是手动构建字符串:
select concat('[{',
string_agg(concat('"', cn, '":', coalesce(convert(varchar(255), value), 'null')
), ','
), '}]'
)
from t
where value <> 0 or value is null
您可以使用动态 sql 来完成。我使用条件聚合来转换 table.
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', '');