Sql server 如何为记录中找到的每个唯一值创建列

Sql server 如何为记录中找到的每个唯一值创建列,sql-server,Sql Server,一个允许用户创建自己的健康调查表表单的web应用程序,每个表单依次允许用户自定义表单,并根据需要为问题和答案添加尽可能多的输入字段。 现在,这些结果存储在两个表中 tblTransaction: ID Person Date FormName ------------------------------------------- 1 John Smith 19/09/2017 FamilyHistory 2 Pat White 18/07/2

一个允许用户创建自己的健康调查表表单的web应用程序,每个表单依次允许用户自定义表单,并根据需要为问题和答案添加尽可能多的输入字段。 现在,这些结果存储在两个表中

tblTransaction

  ID  Person      Date        FormName
 -------------------------------------------
  1   John Smith 19/09/2017   FamilyHistory
  2   Pat White  18/07/2017   FamilyHistory
  2   Pat White  18/07/2017   Diabetes
  ID  TranID   FieldName               Value   
 --------------------------------------------
  1    1       Do you smoke            Yes
  2    1       How many a day          30
  3    2       Cancer in the family    No
  4    2       Blood pressure          No
tbl内容

  ID  Person      Date        FormName
 -------------------------------------------
  1   John Smith 19/09/2017   FamilyHistory
  2   Pat White  18/07/2017   FamilyHistory
  2   Pat White  18/07/2017   Diabetes
  ID  TranID   FieldName               Value   
 --------------------------------------------
  1    1       Do you smoke            Yes
  2    1       How many a day          30
  3    2       Cancer in the family    No
  4    2       Blood pressure          No
我需要根据日期、人员、表单名创建提取,然后将每个表单名找到的每个唯一字段名作为单独的列列出,同时考虑到字段名的计数和值未知

这就是结果应该是什么样子

Date       Person      FormName         Do you smoke    How many a day      
----------------------------------------------------------------------
19/09/2017 John Smith  FamilyHistory    Y               30    
您可以这样做:

SELECT 
  t.Date AS Date,
  t.[Person],
  t.[FormName],
  MAX(CASE WHEN c.FieldName = 'Do you smoke' THEN c.Value END) AS 'Do you smoke',
  MAX(CASE WHEN c.FieldName = 'How many a day' THEN c.Value END) AS 'How many a day',
  MAX(CASE WHEN c.FieldName = 'Cancer in the family' THEN c.Value END) AS 'Cancer in the family',
  MAX(CASE WHEN c.FieldName = 'Blood pressure' THEN c.Value END) AS 'Blood pressure'
FROM tblContent AS c
INNER JOIN tblTransaction AS t ON c.[TranID] = t.[Id]
WHERE t.Person = 'John Smith' AND t.FormName = 'FamilyHistory'
GROUP BY  t.Date,
  t.[Person],
  t.[FormName];

您还可以使用
pivot

SELECT *
FROM
(
    SELECT t.Date,
      t.[Person],
      t.[FormName],
      c.FieldName,
      c.Value
    FROM tblContent AS c
    INNER JOIN tblTransaction AS t ON c.[TranID] = t.[Id]
    WHERE t.Person = 'John Smith' AND t.FormName = 'FamilyHistory'
) AS c
PIVOT
(
   MAX(Value)
   FOR FieldName IN([Do you Smoke], [How many a Day])
) AS p;

为什么需要以这种方式导出?这种数据格式对人类来说是好的,但对计算机来说却是糟糕的。