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

SQL-数组作为选定数据的一部分,sql,sql-server,stored-procedures,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参数,但是数据被混淆

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

基本上,返回的数据表应该如下所示:

SurveyName xyz        (from table no.1)
SurveyTopic abc       (from table no.1)
Optionen [d, v, q, o] (from table no.2)
实现这一目标的最佳方式是什么?创建定义的数据类型? 我尝试使用join参数,但是数据被混淆并返回,就好像有不同的调查,每个都有一个选项。到目前为止,代码如下所示:

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文件的示例数据:

调查

{
    "id": "3f07153f-78cf-4b03-a442-5dbbbdc6c85d",
    "topic": "Internet connection",
    "question": "How fast is you connection?"
}
选项(每个调查都有几个选项)

桌子应该是什么样子的:

{
    "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"}
     ]        
}

根据评论,您似乎需要这样做(某些零件来源于):

样本数据:

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');
查询:

    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;
结果:


结果是一个以管道分隔的列

基于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

嘿,Michael,你能提供一些来自dbo.Surveys和dbo.options的样本数据吗?如果结果是逗号分隔的nvarchar字符串而不是数组,可以吗?如果是这样的话-google for“for xml path(“”)”我添加了一些示例数据,如果您还需要一些,请尽管问!获取字符串中的选项只是最后一个选项,因为我需要使用数组或列表将数据放入特定定义的数据类型中……您是将数据以JSON的形式存储在表中,还是将它们存储在单独的列中,因为在surveys表中有三列id、thema、questionNo,它们位于单独的列中。我只使用json文件,因为它看起来比复制表更清晰。谢谢,看起来不错!我会尽快实施的!:)这个解决方案效果很好,但我在同一次调查中仍然得到了两个答案。是否有可能只得到一个包含数组或选项值列表的响应,如我在上面给出的示例中所示?@MichaelHeribert这或两个结果集是如何作为关系数据正确完成的。但是,您可以将选项序列化到XML列中,该列可以用于将类似数组的数据作为列的一部分传输,而无需使用花哨的黑客(例如CLR UDT)。@MichaelHeribert我正在尝试解决如何做到这一点,但Lucero一针见血,没有简单的方法可以做到这一点。@MichaelHeribert欢迎您。请注意,SQL Server 2016引入了类似于XML的JSON功能(详细信息请参见),但由于尚未广泛部署,我还无法亲自尝试。
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