Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Selecione dados de linha além de dados XML estruturados


Pode ser um pouco mais curto com uma série de 3 CROSS APPLY, nível por nível
 SELECT HistoryId, 
        t.qID,
        t.questionText,
        t.result,
        a.aId,
        a.answerNbr,
        a.answerChosen,
        a.answerTxt
    FROM
        tbl_QuizHistory
    CROSS APPLY QuizData.nodes('quizresult') AS n(q)    
    CROSS APPLY (
        SELECT 
          ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS qID,
          t.q.value('(./questionText)[1]', 'nvarchar(max)') AS questionText,
          t.q.value('(./result)[1]', 'nvarchar(50)') AS result,
          t.q.query('.') queryXml
        FROM 
          n.q.nodes('./question') t(q)
    ) t
    CROSS APPLY (
        SELECT 
          ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS aID,
          q.a.value('(./@number)[1]', 'int') as answerNbr,
          q.a.value('(./@chosen)[1]', 'bit') as answerChosen,
          q.a.value('.','nvarchar(max)') as answerTxt
        FROM
          t.queryXml.nodes('question/answer') q(a)
   ) a;

Se não houver cálculos específicos de nível (por exemplo, row_number() ) são necessários:
 SELECT HistoryId, 
        t.qID,
        t.questionText,
        t.result,
        q.a.value('(./@number)[1]', 'int') as answerNbr,
        q.a.value('(./@chosen)[1]', 'bit') as answerChosen,
        q.a.value('.','nvarchar(max)') as answerTxt
    FROM
        tbl_QuizHistory
    CROSS APPLY QuizData.nodes('quizresult') AS n(q)    
    CROSS APPLY (
        SELECT 
          ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS qID,
          t.q.value('(./questionText)[1]', 'nvarchar(max)') AS questionText,
          t.q.value('(./result)[1]', 'nvarchar(50)') AS result,
          t.q.query('.') queryXml
        FROM n.q.nodes('./question') t(q)
    ) t
    CROSS APPLY t.queryXml.nodes('question/answer') q(a)

Demonstração