格式化T-SQL以返回JSON

时间:2015-03-19 17:46:23

标签: sql sql-server json subquery

我想使用MS SQL Server将我的数据作为JSON返回,并且几乎具有正确的格式,但我被卡住了。我认为我需要另一个子查询,但我似乎无法使子查询正确格式化。

我一直在使用这篇博文作为我的“教程”(XML_JSON),这对我来说非常有帮助。正如您在运行我的查询时所看到的那样,输出接近所需的格式,但我没有正确嵌套“测量”,我认为我需要另一个子查询来使其正确。但是,我不清楚如何进行嵌套......

谢谢!

DECLARE  @tmp_nata TABLE


(FIPS varchar(max),
   Measure VARCHAR(max),
   HAP VARCHAR(max),
   Result float)


INSERT INTO @tmp_nata
  (FIPS, Measure, HAP, Result)
VALUES
  ('00001', 'EnvConcEstimate', 'Benzene', 10.00),
  ('00001', 'EnvConcEstimate', 'Lead', 125.00),
  ('00001', 'EnvConcEstimate', 'Butadiene', 15.00),
  ('00001', 'EnvConcEstimate', 'Acrolein', 10.00),
  ('00001', 'EnvConcEstimate', 'Naphthalene', 15.00),
  ('00001', 'EnvConcEstimate', 'Formaldehyde', 10.00),
  ('00001', 'EnvConcEstimate', 'PAH', 125.00),
  ('00001', 'EnvConcEstimate', 'Acetaldehyde', 15.00),
  ('00001', 'EnvConcEstimate', 'Arsenic', 10.00),
  ('00001', 'EnvConcEstimate', 'Chromium', 15.00),
  ('00001', 'EnvConcEstimate', 'Diesel PM', 10.00),

  ('00001', 'NeuroNonCancer_HQ', 'Lead', 125.00),
  ('00001', 'Cum_AirToxicNonCancerNeuro', 'None', 15.00),
  ('00001', 'Cum_AirToxicNonCancerRespir', 'None', 10.00),
  ('00001', 'Cum_AirToxicCancer', 'None', 15.00),

  ('00001', 'RespNonCancer_HQ', 'Acrolein', 10.00),
  ('00001', 'RespNonCancer_HQ', 'Formaldehyde', 125.00),
  ('00001', 'RespNonCancer_HQ', 'Acetaldehyde', 15.00),
  ('00001', 'RespNonCancer_HQ', 'Diesel PM', 10.00),
  ('00001', 'RespNonCancer_HQ', 'Chromium', 15.00),
  ('00001', 'RespNonCancer_HQ', 'Naphthalene', 10.00),

  ('00001', 'HealthRiskEstimate', 'Benzene', 125.00),
  ('00001', 'HealthRiskEstimate', 'Butadiene', 15.00),
  ('00001', 'HealthRiskEstimate', 'Formaldehyde', 10.00),
  ('00001', 'HealthRiskEstimate', 'PAH', 15.00),
  ('00001', 'HealthRiskEstimate', 'Acetaldehyde', 10.00),
  ('00001', 'HealthRiskEstimate', 'Arsenic', 125.00),
  ('00001', 'HealthRiskEstimate', 'Chromium', 125.00),
  ('00001', 'HealthRiskEstimate', 'Naphthalene', 15.00),

  ('00001', 'HumanExpEstimate', 'Benzene', 10.00),
  ('00001', 'HumanExpEstimate', 'Lead', 125.00),
  ('00001', 'HumanExpEstimate', 'Butadiene', 15.00),
  ('00001', 'HumanExpEstimate', 'Acrolein', 10.00),
  ('00001', 'HumanExpEstimate', 'Naphthalene', 15.00),
  ('00001', 'HumanExpEstimate', 'Formaldehyde', 10.00),
  ('00001', 'HumanExpEstimate', 'PAH', 125.00),
  ('00001', 'HumanExpEstimate', 'Acetaldehyde', 15.00),
  ('00001', 'HumanExpEstimate', 'Arsenic', 10.00),
  ('00001', 'HumanExpEstimate', 'Chromium', 15.00),
  ('00001', 'HumanExpEstimate', 'Diesel PM', 10.00),

  ('20000', 'EnvConcEstimate', 'Benzene', 210.00),
  ('20000', 'EnvConcEstimate', 'Lead', 2125.00),
  ('20000', 'EnvConcEstimate', 'Butadiene', 215.00),
  ('20000', 'EnvConcEstimate', 'Acrolein', 250.00),
  ('20000', 'EnvConcEstimate', 'Naphthalene', 275.00),
  ('20000', 'EnvConcEstimate', 'Formaldehyde', 210.00),
  ('20000', 'EnvConcEstimate', 'PAH', 2125.00),
  ('20000', 'EnvConcEstimate', 'Acetaldehyde', 215.00),
  ('20000', 'EnvConcEstimate', 'Arsenic', 250.00),
  ('20000', 'EnvConcEstimate', 'Chromium', 275.00),
  ('20000', 'EnvConcEstimate', 'Diesel PM', 210.00),
  ('20000', 'NeuroNonCancer_HQ', 'Lead', 2125.00),
  ('20000', 'Cum_AirToxicNonCancerNeuro', 'None', 215.00),
  ('20000', 'Cum_AirToxicNonCancerRespir', 'None', 250.00),
  ('20000', 'Cum_AirToxicCancer', 'None', 275.00),

  ('20000', 'RespNonCancer_HQ', 'Acrolein', 210.00),
  ('20000', 'RespNonCancer_HQ', 'Formaldehyde', 2125.00),
  ('20000', 'RespNonCancer_HQ', 'Acetaldehyde', 215.00),
  ('20000', 'RespNonCancer_HQ', 'Diesel PM', 250.00),
  ('20000', 'RespNonCancer_HQ', 'Chromium', 75.00),
  ('20000', 'RespNonCancer_HQ', 'Naphthalene', 210.00),

  ('20000', 'HealthRiskEstimate', 'Benzene', 2125.00),
  ('20000', 'HealthRiskEstimate', 'Butadiene', 215.00),
  ('20000', 'HealthRiskEstimate', 'Formaldehyde', 250.00),
  ('20000', 'HealthRiskEstimate', 'PAH', 275.00),
  ('20000', 'HealthRiskEstimate', 'Acetaldehyde', 210.00),
  ('20000', 'HealthRiskEstimate', 'Arsenic', 2125.00),
  ('20000', 'HealthRiskEstimate', 'Chromium', 2125.00),
  ('20000', 'HealthRiskEstimate', 'Naphthalene', 215.00),

  ('20000', 'HumanExpEstimate', 'Benzene', 210.00),
  ('20000', 'HumanExpEstimate', 'Lead', 2125.00),
  ('20000', 'HumanExpEstimate', 'Butadiene', 215.00),
  ('20000', 'HumanExpEstimate', 'Acrolein', 250.00),
  ('20000', 'HumanExpEstimate', 'Naphthalene', 275.00),
  ('20000', 'HumanExpEstimate', 'Formaldehyde', 210.00),
  ('20000', 'HumanExpEstimate', 'PAH', 2125.00),
  ('20000', 'HumanExpEstimate', 'Acetaldehyde', 215.00),
  ('20000', 'HumanExpEstimate', 'Arsenic', 250.00),
  ('20000', 'HumanExpEstimate', 'Chromium', 275.00),
  ('20000', 'HumanExpEstimate', 'Diesel PM', 210.00) 

SELECT * from @tmp_nata

  SELECT
  FIPS, 
    STUFF((SELECT
          (',"' + SUB.Measure + '":{"'+ SUB.HAP+ '":' + CAST(Result as varchar(max)) + '}')
           FROM @tmp_nata SUB
           WHERE SUB.FIPS = AT.FIPS
           ORDER BY SUB.FIPS, SUB.Measure, SUB.HAP ASC
           FOR XML PATH('')
           ), 1, 1, '')  AS JSON
FROM @tmp_nata AT
WHERE 1 = 1
GROUP BY FIPS

所需的输出是每个FIPS一个JSON,对于FIPS = 00001,它看起来像这样:

{
    "EnvConcEstimate": {
        "Benzene": 10,
        "Lead": 125,
        "Butadiene": 15,
        "Acrolein": 10,
        "Naphthalene": 15,
        "Formaldehyde": 10,
        "PAH": 125,
        "Acetaldehyde": 15,
        "Arsenic": 10,
        "Chromium": 15,
        "Diesel PM": 10
    },
    "NeuroNonCancer_HQ": {
        "Lead": 125
    },
    "Cum_AirToxicNonCancerNeuro": {
        "None": 15
    },
    "Cum_AirToxicNonCancerRespir": {
        "None": 10
    },
    "Cum_AirToxicCancer": {
        "None": 15
    },
    "RespNonCancer_HQ": {
        "Acrolein": 10,
        "Formaldehyde": 125,
        "Acetaldehyde": 15,
        "Diesel PM": 10,
        "Chromium": 15,
        "Naphthalene": 10
    },
    "HealthRiskEstimate": {
        "Benzene": 125,
        "Butadiene": 15,
        "Formaldehyde": 10,
        "PAH": 15,
        "Acetaldehyde": 10,
        "Arsenic": 125,
        "Chromium": 125,
        "Naphthalene": 15
    },
    "HumanExpEstimate": {
        "Benzene": 10,
        "Lead": 125,
        "Butadiene": 15,
        "Acrolein": 10,
        "Naphthalene": 15,
        "Formaldehyde": 10,
        "PAH": 125,
        "Acetaldehyde": 15,
        "Arsenic": 10,
        "Chromium": 15,
        "Diesel PM": 10
    }
}

2 个答案:

答案 0 :(得分:2)

你需要两次应用你的逻辑,首先是haps和结果,然后是测量。您可以通过CTE执行此操作,例如:

;WITH cte AS(
SELECT
  FIPS, '"' + Measure +'":{'+
    STUFF((SELECT
          (',"' + SUB.HAP + '":'+CAST(Result AS VARCHAR(MAX)) + '')
           FROM t SUB
           WHERE SUB.FIPS = AT.FIPS AND SUB.Measure = AT.Measure
           ORDER BY SUB.Measure, SUB.HAP
           FOR XML PATH('')
           ), 1, 1, '') + '}' AS JSON
FROM t AT
GROUP BY FIPS, Measure)

SELECT FIPS, 
'{' + STUFF((SELECT
          (',' + JSON)
           FROM cte SUB
           WHERE SUB.FIPS = AT.FIPS
           ORDER BY SUB.FIPS
           FOR XML PATH('')
           ), 1, 1, '') + '}' AS JSON
           FROM cte AS AT
GROUP BY FIPS

示例输出:

00001   {"EnvConcEstimate":{"Benzene":10,"Lead":125},"NeuroNonCancer_HQ":{"Lead":125}}
20000   {"Cum_AirToxicCancer":{"None":275},"Cum_AirToxicNonCancerNeuro":{"None":215},"Cum_AirToxicNonCancerRespir":{"None":250},"EnvConcEstimate":{"Benzene":210,"Lead":2125},"NeuroNonCancer_HQ":{"Lead":2125}}

小提琴:http://sqlfiddle.com/#!6/c73e4/13

答案 1 :(得分:0)

刚刚解决了你的问题,我在不使用FOR XML PATH的情况下尝试了它,我每行创建了另一个表变量with an extra field to build jason object,我从主表插入声明的表然后通过选中PIPSMeasure为每行构建json对象。任何人都可以执行以下代码并检查结果HERE


架构:

CREATE TABLE tmp_nata TABLE
(FIPS varchar(max),
   Measure VARCHAR(max),
   HAP VARCHAR(max),
   Result float)


INSERT INTO @tmp_nata
  (FIPS, Measure, HAP, Result)
VALUES
  ('00001', 'EnvConcEstimate', 'Benzene', 10.00),
  ('00001', 'EnvConcEstimate', 'Lead', 125.00),
  ('00001', 'EnvConcEstimate', 'Butadiene', 15.00),
  ('00001', 'EnvConcEstimate', 'Acrolein', 10.00),
  ('00001', 'EnvConcEstimate', 'Naphthalene', 15.00),
  ('00001', 'EnvConcEstimate', 'Formaldehyde', 10.00),
  ('00001', 'EnvConcEstimate', 'PAH', 125.00),
  ('00001', 'EnvConcEstimate', 'Acetaldehyde', 15.00),
  ('00001', 'EnvConcEstimate', 'Arsenic', 10.00),
  ('00001', 'EnvConcEstimate', 'Chromium', 15.00),
  ('00001', 'EnvConcEstimate', 'Diesel PM', 10.00),

  ('00001', 'NeuroNonCancer_HQ', 'Lead', 125.00),
  ('00001', 'Cum_AirToxicNonCancerNeuro', 'None', 15.00),
  ('00001', 'Cum_AirToxicNonCancerRespir', 'None', 10.00),
  ('00001', 'Cum_AirToxicCancer', 'None', 15.00),

  ('00001', 'RespNonCancer_HQ', 'Acrolein', 10.00),
  ('00001', 'RespNonCancer_HQ', 'Formaldehyde', 125.00),
  ('00001', 'RespNonCancer_HQ', 'Acetaldehyde', 15.00),
  ('00001', 'RespNonCancer_HQ', 'Diesel PM', 10.00),
  ('00001', 'RespNonCancer_HQ', 'Chromium', 15.00),
  ('00001', 'RespNonCancer_HQ', 'Naphthalene', 10.00),

  ('00001', 'HealthRiskEstimate', 'Benzene', 125.00),
  ('00001', 'HealthRiskEstimate', 'Butadiene', 15.00),
  ('00001', 'HealthRiskEstimate', 'Formaldehyde', 10.00),
  ('00001', 'HealthRiskEstimate', 'PAH', 15.00),
  ('00001', 'HealthRiskEstimate', 'Acetaldehyde', 10.00),
  ('00001', 'HealthRiskEstimate', 'Arsenic', 125.00),
  ('00001', 'HealthRiskEstimate', 'Chromium', 125.00),
  ('00001', 'HealthRiskEstimate', 'Naphthalene', 15.00),

  ('00001', 'HumanExpEstimate', 'Benzene', 10.00),
  ('00001', 'HumanExpEstimate', 'Lead', 125.00),
  ('00001', 'HumanExpEstimate', 'Butadiene', 15.00),
  ('00001', 'HumanExpEstimate', 'Acrolein', 10.00),
  ('00001', 'HumanExpEstimate', 'Naphthalene', 15.00),
  ('00001', 'HumanExpEstimate', 'Formaldehyde', 10.00),
  ('00001', 'HumanExpEstimate', 'PAH', 125.00),
  ('00001', 'HumanExpEstimate', 'Acetaldehyde', 15.00),
  ('00001', 'HumanExpEstimate', 'Arsenic', 10.00),
  ('00001', 'HumanExpEstimate', 'Chromium', 15.00),
  ('00001', 'HumanExpEstimate', 'Diesel PM', 10.00),

  ('20000', 'EnvConcEstimate', 'Benzene', 210.00),
  ('20000', 'EnvConcEstimate', 'Lead', 2125.00),
  ('20000', 'EnvConcEstimate', 'Butadiene', 215.00),
  ('20000', 'EnvConcEstimate', 'Acrolein', 250.00),
  ('20000', 'EnvConcEstimate', 'Naphthalene', 275.00),
  ('20000', 'EnvConcEstimate', 'Formaldehyde', 210.00),
  ('20000', 'EnvConcEstimate', 'PAH', 2125.00),
  ('20000', 'EnvConcEstimate', 'Acetaldehyde', 215.00),
  ('20000', 'EnvConcEstimate', 'Arsenic', 250.00),
  ('20000', 'EnvConcEstimate', 'Chromium', 275.00),
  ('20000', 'EnvConcEstimate', 'Diesel PM', 210.00),
  ('20000', 'NeuroNonCancer_HQ', 'Lead', 2125.00),
  ('20000', 'Cum_AirToxicNonCancerNeuro', 'None', 215.00),
  ('20000', 'Cum_AirToxicNonCancerRespir', 'None', 250.00),
  ('20000', 'Cum_AirToxicCancer', 'None', 275.00),

  ('20000', 'RespNonCancer_HQ', 'Acrolein', 210.00),
  ('20000', 'RespNonCancer_HQ', 'Formaldehyde', 2125.00),
  ('20000', 'RespNonCancer_HQ', 'Acetaldehyde', 215.00),
  ('20000', 'RespNonCancer_HQ', 'Diesel PM', 250.00),
  ('20000', 'RespNonCancer_HQ', 'Chromium', 75.00),
  ('20000', 'RespNonCancer_HQ', 'Naphthalene', 210.00),

  ('20000', 'HealthRiskEstimate', 'Benzene', 2125.00),
  ('20000', 'HealthRiskEstimate', 'Butadiene', 215.00),
  ('20000', 'HealthRiskEstimate', 'Formaldehyde', 250.00),
  ('20000', 'HealthRiskEstimate', 'PAH', 275.00),
  ('20000', 'HealthRiskEstimate', 'Acetaldehyde', 210.00),
  ('20000', 'HealthRiskEstimate', 'Arsenic', 2125.00),
  ('20000', 'HealthRiskEstimate', 'Chromium', 2125.00),
  ('20000', 'HealthRiskEstimate', 'Naphthalene', 215.00),

  ('20000', 'HumanExpEstimate', 'Benzene', 210.00),
  ('20000', 'HumanExpEstimate', 'Lead', 2125.00),
  ('20000', 'HumanExpEstimate', 'Butadiene', 215.00),
  ('20000', 'HumanExpEstimate', 'Acrolein', 250.00),
  ('20000', 'HumanExpEstimate', 'Naphthalene', 275.00),
  ('20000', 'HumanExpEstimate', 'Formaldehyde', 210.00),
  ('20000', 'HumanExpEstimate', 'PAH', 2125.00),
  ('20000', 'HumanExpEstimate', 'Acetaldehyde', 215.00),
  ('20000', 'HumanExpEstimate', 'Arsenic', 250.00),
  ('20000', 'HumanExpEstimate', 'Chromium', 275.00),
  ('20000', 'HumanExpEstimate', 'Diesel PM', 210.00) 

查询:

DECLARE
    @FIPS VARCHAR(50),
    @Measure VARCHAR(50),
    @Vals VARCHAR(MAX);

SET @FIPS ='';
SET @Measure ='';
SET @Vals ='';

DECLARE @t TABLE
(
    FIPS VARCHAR(50),
    Measure VARCHAR(50),
    HAP VARCHAR(50),
    Result FLOAT,
    Vals VARCHAR(MAX)
 ); 

INSERT @t(FIPS,Measure,HAP,Result)
SELECT FIPS,Measure,HAP,Result FROM tmp_nata
ORDER BY FIPS,Measure,HAP;


UPDATE @t 
SET @Vals = Vals =
    CASE @FIPS
         WHEN FIPS THEN
                   CASE @Measure
                        WHEN Measure THEN 
                                     @Vals +', "'+ HAP + '":'+cast(Result as varchar(100))
                        ELSE @Vals +'}, "'+Measure+'": {"'+ HAP + '":'+cast(Result as varchar(100))
                   END
         ELSE  '{ "'+Measure+'": {'+' "'+ HAP + '":'+cast(Result as varchar(100))
         END,
    @FIPS=FIPS, 
    @Measure = Measure;



SELECT DISTINCT FIPS, Vals= MAX(Vals)+'}}'
FROM @t
GROUP BY FIPS
ORDER BY FIPS;

输出:

FIPS    Vals
00001   { "EnvConcEstimate": { "Benzene":10, "Lead":125, "Butadiene":15, "Acrolein":10, "Naphthalene":15, "Formaldehyde":10, "PAH":125, "Acetaldehyde":15, "Arsenic":10, "Chromium":15, "Diesel PM":10}, "NeuroNonCancer_HQ": {"Lead":125}, "Cum_AirToxicNonCancerNeuro": {"None":15}, "Cum_AirToxicNonCancerRespir": {"None":10}, "Cum_AirToxicCancer": {"None":15}, "RespNonCancer_HQ": {"Acrolein":10, "Formaldehyde":125, "Acetaldehyde":15, "Diesel PM":10, "Chromium":15, "Naphthalene":10}, "HealthRiskEstimate": {"Benzene":125, "Butadiene":15, "Formaldehyde":10, "PAH":15, "Acetaldehyde":10, "Arsenic":125, "Chromium":125, "Naphthalene":15}, "HumanExpEstimate": {"Benzene":10, "Lead":125, "Butadiene":15, "Acrolein":10, "Naphthalene":15, "Formaldehyde":10, "PAH":125, "Acetaldehyde":15, "Arsenic":10, "Chromium":15, "Diesel PM":10}}
20000   { "EnvConcEstimate": { "Benzene":210, "Lead":2125, "Butadiene":215, "Acrolein":250, "Naphthalene":275, "Formaldehyde":210, "PAH":2125, "Acetaldehyde":215, "Arsenic":250, "Chromium":275, "Diesel PM":210}, "NeuroNonCancer_HQ": {"Lead":2125}, "Cum_AirToxicNonCancerNeuro": {"None":215}, "Cum_AirToxicNonCancerRespir": {"None":250}, "Cum_AirToxicCancer": {"None":275}, "RespNonCancer_HQ": {"Acrolein":210, "Formaldehyde":2125, "Acetaldehyde":215, "Diesel PM":250, "Chromium":75, "Naphthalene":210}, "HealthRiskEstimate": {"Benzene":2125, "Butadiene":215, "Formaldehyde":250, "PAH":275, "Acetaldehyde":210, "Arsenic":2125, "Chromium":2125, "Naphthalene":215}, "HumanExpEstimate": {"Benzene":210, "Lead":2125, "Butadiene":215, "Acrolein":250, "Naphthalene":275, "Formaldehyde":210, "PAH":2125, "Acetaldehyde":215, "Arsenic":250, "Chromium":275, "Diesel PM":210}}