SQL - 数组作为选定数据的一部分

时间:2016-03-23 20:44:52

标签: sql sql-server stored-procedures

我正在尝试从mssql中的两个不同表中检索调查数据集。每个调查都有一些回答选项,应该作为检索数据表的一部分在数组中返回。

基本上,返回的数据表应该是这样的:

SurveyName xyz        (from table no.1)
SurveyTopic abc       (from table no.1)
Optionen [d, v, q, o] (from table no.2)

实现这一目标的最佳方法是什么?创建定义的数据类型? 我尝试使用join-argument,但随后数据混淆并返回,就好像有不同的调查,每个调查都有一个选项。到目前为止代码看起来像这样:

CREATE PROCEDURE dbo.GetSurvey
    @Id nvarchar (128)
AS
    SELECT Surveys.*, Options,*
    FROM dbo.Surveys
    JOIN Options
    ON Options.SurveyId = Survey.Id
    WHERE Surveys.Id = @Id

以下是json-files的一些示例数据:

调查

{
    "id": "3f07153f-78cf-4b03-a442-5dbbbdc6c85d",
    "topic": "Internet connection",
    "question": "How fast is you connection?"
}

选项(每项调查都有一些)

{
    "id":"3b3f9583-7d09-49d2-baee-d724c6ce3d9d",
    "surveyId":"3f07153f-78cf-4b03-a442-5dbbbdc6c85d",
    "answer":"10mbit/s"
}

表格应该是什么样的:

{
    "id": "3f07153f-78cf-4b03-a442-5dbbbdc6c85d",
    "topic": "Internet connection",
    "question": "How fast is you connection?"
    "options":[
        {"id":"85c1ae87-7da9-41c4-9046-22df231af6ec",
         "surveyId":"3f07153f-78cf-4b03-a442-5dbbbdc6c85d",
         "answer":"10mbit/s"}

        {"id":"55347f11-c01f-4b5f-86a3-9d9c66c2aef5",
         "surveyId":"3f07153f-78cf-4b03-a442-5dbbbdc6c85d",
         "answer":"20mbit/s"}
     ]        
}

2 个答案:

答案 0 :(得分:1)

基于评论看起来你需要这样做(某些部分来自here):

示例数据:

IF OBJECT_ID('tempdb..#Surveys') IS NOT NULL
    DROP TABLE #Surveys;

CREATE TABLE #Surveys(id       UNIQUEIDENTIFIER
                , thema    VARCHAR(100)
                , question VARCHAR(250));

INSERT INTO #Surveys
VALUES
      ('3f07153f-78cf-4b03-a442-5dbbbdc6c85d'
     , 'Internet connection'
     , 'How fast is you connection?'),
          ('3f07153f-78cf-4b03-a442-5dbbbdc6c85c'
     , 'Internet connection'
     , 'How fast was your old connection?');

IF OBJECT_ID('tempdb..#Option') IS NOT NULL
    DROP TABLE #Option;

CREATE TABLE #Option(Id       UNIQUEIDENTIFIER
                , SurveyId UNIQUEIDENTIFIER
                , Answer   VARCHAR(250));

INSERT INTO #Option
VALUES
      ('3b3f9583-7d09-49d2-baee-d724c6ce3d9d'
     , '3f07153f-78cf-4b03-a442-5dbbbdc6c85d'
     , '10mbit/s'),
      ('55347f11-c01f-4b5f-86a3-9d9c66c2aef5'
     , '3f07153f-78cf-4b03-a442-5dbbbdc6c85d'
     , '20mbit/s'),
      ('55347f11-c01f-4b5f-86a3-9d9c66c2aef5'
     , '3f07153f-78cf-4b03-a442-5dbbbdc6c85c'
     , '5mbit/s'),
      ('55347f11-c01f-4b5f-86a3-9d9c66c2aef5'
     , '3f07153f-78cf-4b03-a442-5dbbbdc6c85c'
     , '10mbit/s');

QUERY:

    IF OBJECT_ID('tempdb..#tempRes') IS NOT NULL
    DROP TABLE #tempRes;
  SELECT A.id
            , A.thema
            , A.question
            , [Options] = CAST(B.Id AS VARCHAR(36))+', '+B.Answer 
            INTO #tempRes
        FROM   #Surveys AS A
             JOIN #Option AS B ON B.SurveyId = A.Id;

WITH Ranked ( id,thema,question,rnk, [Options] ) 
             AS ( SELECT id,thema,question,rnk = ROW_NUMBER() OVER( PARTITION BY id ORDER BY id ),
                         [Options]=CAST( [Options] AS VARCHAR(8000) ) FROM #tempRes ),
   AnchorRanked ( id,thema,question,rnk, [Options] ) 
             AS ( SELECT id,thema,question,rnk, [Options]
                    FROM Ranked
                   WHERE rnk = 1 ),
RecurRanked ( id,thema,question,rnk, [Options])
             AS ( SELECT id,thema,question,rnk, [Options]
                    FROM AnchorRanked
                   UNION ALL
                  SELECT Ranked.id, Ranked.thema,Ranked.question, Ranked.rnk,
                         RecurRanked.[Options] + '|' + Ranked.[Options]
                    FROM Ranked
                   INNER JOIN RecurRanked
                      ON Ranked.id = RecurRanked.id
                     AND Ranked.rnk = RecurRanked.rnk + 1 )
SELECT id,thema,question, MAX( [Options] )
      FROM RecurRanked
  GROUP BY id,thema,question;

结果:

enter image description here

结果是以管道分隔的列

答案 1 :(得分:1)

在Kamran Farzami的解决方案的基础上,您可以使用XML查询将选项填充到单行的单个列中。

SELECT A.id, A.thema, A.question, (
        SELECT * 
        FROM [Option] B 
        WHERE B.SurveyId = A.Id 
        FOR XML PATH('option'), ROOT('options'), TYPE
    ) AS options
    FROM Surveys AS A

http://sqlfiddle.com/#!6/0978e/3/0