查询XML列与另一个

时间:2013-12-08 12:59:58

标签: sql-server xquery

我的用户表包含一个xml列,用于存储人口统计信息的用户定义字段,这些字段来自个人资料调查问卷。

用户的人口统计样本条目:

 <demographics>
      <question_1>answer_1</question_1>
      <question_2>answer_2</question_2>
      <question_3>answer_3</question_3>
    </demographics>

分配表有另一个用于资格的xml列,这也是基于个人资料调查问卷。

<Eligibility>
  <Expression>
    <Question>question_1</Question>
    <Answer>answer_1</Answer>
  </Expression>
  <Expression>
    <Question>question_3</Question>
    <Answer>answer_3</Answer>
  </Expression>
</Eligibility>

我需要根据表格中定义的xml资格标准找到与用户的受众特征匹配的所有分配。 资格标准之间的运营商必须是'AND'。下面列出的是我写的查询

SELECT * 
    FROM Assignments AS a
    WHERE Eligibility.exist('/Eligibility/Expression[Question= 1 and Answer=1]') = 1 
    AND Eligibility.exist('/Eligibility/Expression[Question= 2 and Answer=2]') = 1 

假设我们有两个分配A1和A2。 A1的标准为Question1 = Answer1,A2的标准为Question2 = Answer2。两项任务都满足用户的资格。但是,由于资格标准之间存在“AND”,因此上述查询不会返回两个分配中的任何一个。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:4)

这实际上是一个使用XML数据的relational division查询。

代码中的注释描述了查询的每个部分的内容。

-- A users demographics
declare @UserDem xml = '
<demographics>
  <question_1>answer_1</question_1>
  <question_2>answer_2</question_2>
  <question_3>answer_3</question_3>
</demographics>';

-- Get ID for the assignment
select A.ID
from Assignments as A 
  -- Calculate the number of Expression there are in each assignment
  cross apply (select A.Eligibility.value('count(/Eligibility/Expression)', 'int')) as C(ECount)
  -- Shred on Expression 
  cross apply A.Eligibility.nodes('/Eligibility/Expression') as E(X)
  -- Join to demographics on question and answer
  inner join @UserDem.nodes('demographics/*') as D(X)
    on D.X.value('local-name(.)[1]', 'nvarchar(100)') = E.X.value('(Question/text())[1]', 'nvarchar(100)') and
       D.X.value('text()[1]', 'nvarchar(100)') = E.X.value('(Answer/text())[1]', 'nvarchar(100)')
-- Group on ID and get the Assignments that are fully covered by the demographic
group by A.ID, C.ECount
having count(*) = C.ECount;

SQL Fiddle