2017-04-10 45 views
1

我有一个表的格式如下Sql Server的转动命令基于文本给空细胞

╔════════╦══════════════╦════════╦════════════╦══════════╦════════╦══════════╦══════════╗ 
║ Answer ║ QuestionText ║ type ║ QuestionID ║ ResultID ║ Action ║ Username ║ SurveyID ║ 
╠════════╬══════════════╬════════╬════════════╬══════════╬════════╬══════════╬══════════╣ 
║ FN 1 ║ First Name ║ text ║ 3467  ║ 2259  ║ 2259 ║ admin ║ 308  ║ 
║ LN 1 ║ Last Name ║ text ║ 3468  ║ 2259  ║ 2259 ║ admin ║ 308  ║ 
║ Male ║ Gender  ║ radio ║ 3466  ║ 2259  ║ 2259 ║ admin ║ 308  ║ 
║ 12  ║ Age   ║ number ║ 3469  ║ 2259  ║ 2259 ║ admin ║ 308  ║ 
║ FN 2 ║ First Name ║ text ║ 3467  ║ 2260  ║ 2260 ║ admin ║ 308  ║ 
║ LN 2 ║ Last Name ║ text ║ 3468  ║ 2260  ║ 2260 ║ admin ║ 308  ║ 
║ Female ║ Gender  ║ radio ║ 3466  ║ 2260  ║ 2260 ║ admin ║ 308  ║ 
║ 12  ║ Age   ║ number ║ 3469  ║ 2260  ║ 2260 ║ admin ║ 308  ║ 
╚════════╩══════════════╩════════╩════════════╩══════════╩════════╩══════════╩══════════╝ 

我使用下面的支点查询它试图支点。

SELECT [ResultID],[Username],[Action],[First Name],[Last Name],[Gender],[Age] from 
      (
       select * 
       from #myTab 
      ) as y 
      pivot 
      (
       max(Answer) 
       for QuestionText in ([First Name],[Last Name],[Gender],[Age]) 
      ) as p 

但我得到下表为支点结果

╔══════════╦══════════╦════════╦════════════╦═══════════╦════════╦══════╗ 
║ ResultID ║ Username ║ Action ║ First Name ║ Last Name ║ Gender ║ Age ║ 
╠══════════╬══════════╬════════╬════════════╬═══════════╬════════╬══════╣ 
║ 2259  ║ admin ║ 2259 ║ NULL  ║ NULL  ║ NULL ║ 12 ║ 
║ 2260  ║ admin ║ 2260 ║ NULL  ║ NULL  ║ NULL ║ 12 ║ 
║ 2259  ║ admin ║ 2259 ║ NULL  ║ NULL  ║ Male ║ NULL ║ 
║ 2260  ║ admin ║ 2260 ║ NULL  ║ NULL  ║ Female ║ NULL ║ 
║ 2259  ║ admin ║ 2259 ║ FN 1  ║ NULL  ║ NULL ║ NULL ║ 
║ 2260  ║ admin ║ 2260 ║ FN 2  ║ NULL  ║ NULL ║ NULL ║ 
║ 2259  ║ admin ║ 2259 ║ NULL  ║ LN 1  ║ NULL ║ NULL ║ 
║ 2260  ║ admin ║ 2260 ║ NULL  ║ LN 2  ║ NULL ║ NULL ║ 
╚══════════╩══════════╩════════╩════════════╩═══════════╩════════╩══════╝ 

我不知道为什么我收到所有这些NULL值。这将是一个很大的帮助,如果有人能告诉我这是为什么发生的,而正确的方式来获得以下支点输出:

╔══════════╦══════════╦════════╦════════════╦═══════════╦════════╦══════╗ 
║ ResultID ║ Username ║ Action ║ First Name ║ Last Name ║ Gender ║ Age ║ 
╠══════════╬══════════╬════════╬════════════╬═══════════╬════════╬══════╣ 
║ 2259  ║ admin ║ 2259 ║ FN 1  ║ LN 1  ║ Male ║ 12 ║ 
║ 2260  ║ admin ║ 2260 ║ FN 2  ║ LN 2  ║ Female ║ 12 ║ 
╚══════════╩══════════╩════════╩════════════╩═══════════╩════════╩══════╝ 

Source table in csv format

+0

唉唉,ASCII表...:d –

+0

您需要选择只有你的子查询所需的列。我更喜欢条件聚合到'pivot'语法。 –

回答

1

这是正常现象......你应该使用一组由一个聚合函数(如MAX()或第()或字符串连接(也许东西吗?)根据您的要求),以减少的结果,每个实体单行(由键,你组上定义)

编辑:尝试;

SELECT 
[ResultID], 
max([Username]) as Username, 
max([Action]) as action, 
max([First Name]) as FirstName, 
max([Last Name]) as LastName, 
max([Gender]) as gender, 
max([Age]) as age from 
      (
       select * 
       from #myTab 
      ) as y 
      pivot 
      (
       max(Answer) 
       for QuestionText in ([First Name],[Last Name],[Gender],[Age]) 
      ) as p 
GROUP BY 
    ResultId 
+0

我很想知道如何。因为我对sql服务器和数据透视过程相当陌生。我没有所需的词汇来搜索并在计算器中找到它。如果您可以告诉我如何应用该群组,或者可以将该问题标记为重复。我会感激你 – insomniac

+0

@insomniac尝试例如我编辑 – Milney

+0

谢谢你,这对我的作品,而所有其他的答案 – insomniac

2

只是限制要求X轴,Y轴(n)和值

Select [ResultID],[Username],[Action],[First Name],[Last Name],[Gender],[Age] 
From (
     Select resultid 
       ,Action 
       ,Username 
       ,questiontext 
       ,answer 
     From #Table21 
    ) y 
    pivot (max(Answer) for QuestionText in ([First Name],[Last Name],[Gender],[Age])) P 
+0

这仍然没有帮助,他仍然需要一个组,以获得每行只有一行 – Milney

+0

这是脆弱的,因为表可能会改变,然后它会随机停止工作......重复行仍然会产生重复。这在我看来是懒惰的,我不会让过去的代码审查 - 更安全的聚合 – Milney

+0

谢谢。我已经尝试过这个答案,它也可以 – insomniac

1
CREATE TABLE #Table21 
    ([Answer] varchar(6), [QuestionText] varchar(10), [type] varchar(6), [QuestionID] int, [ResultID] int, [Action] int, [Username] varchar(5), [SurveyID] int) 
; 

INSERT INTO #Table21 
    ([Answer], [QuestionText], [type], [QuestionID], [ResultID], [Action], [Username], [SurveyID]) 
VALUES 
    ('FN 1', 'First Name', 'text', 3467, 2259, 2259, 'admin', 308), 
    ('LN 1', 'Last Name', 'text', 3468, 2259, 2259, 'admin', 308), 
    ('Male', 'Gender', 'radio', 3466, 2259, 2259, 'admin', 308), 
    ('12', 'Age', 'number', 3469, 2259, 2259, 'admin', 308), 
    ('FN 2', 'First Name', 'text', 3467, 2260, 2260, 'admin', 308), 
    ('LN 2', 'Last Name', 'text', 3468, 2260, 2260, 'admin', 308), 
    ('Female', 'Gender', 'radio', 3466, 2260, 2260, 'admin', 308), 
    ('12', 'Age', 'number', 3469, 2260, 2260, 'admin', 308) 

with cte as 
(
SELECT [ResultID],[Username],[Action],[First Name],[Last Name],[Gender],[Age] from 
      (
       select * 
       from #Table21 
      ) as y 
      pivot 
      (
       max(Answer) 
       for QuestionText in ([First Name],[Last Name],[Gender],[Age]) 
      ) as p 
      ) 


SELECT 
    [ResultID], 
    max([Username]) AS [Username], 
    MAX([Action]) AS [Action], 
    MAX([First Name]) AS [First Name], 
    MAX([Last Name]) AS [Last Name] , 
    MAX([Gender]) AS [Gender], 
    MAX([Age]) AS [Age] 
FROM CTE 
GROUP BY [ResultID]; 

输出

ResultID Username Action First Name Last Name Gender Age 
2259 admin 2259 FN 1 LN 1 Male 12 
2260 admin 2260 FN 2 LN 2 Female 12 
-1

您还可以使用CASE表达式与领域聚合基本上PIVOT结果。我经常使用它,因为如果由于某种原因,我想添加另一个聚合列,而不必再做另一个PIVOT。在某些情况下它也更快。

SELECT 
    [ResultID], 
    [UserName], 
    [Action], 
    MAX(CASE WHEN c.[QuestionText] = 'First Name' THEN [Answer] END) as [First Name], 
    MAX(CASE WHEN c.[QuestionText] = 'Last Name' THEN [Answer] END) as [Last Name], 
    MAX(CASE WHEN c.[QuestionText] = 'Gender' THEN [Answer] END) as [Gender], 
    MAX(CASE WHEN c.[QuestionText] = 'Age' THEN [Answer] END) as [Age] 
FROM 
    cte c 
GROUP BY 
    [ResultID], 
    [UserName], 
    [Action] 

例如:

WITH cte AS (SELECT * FROM (
VALUES 
    ('FN 1', 'First Name', 'text', 3467, 2259, 2259, 'admin', 308), 
    ('LN 1', 'Last Name', 'text', 3468, 2259, 2259, 'admin', 308), 
    ('Male', 'Gender', 'radio', 3466, 2259, 2259, 'admin', 308), 
    ('12', 'Age', 'number', 3469, 2259, 2259, 'admin', 308), 
    ('FN 2', 'First Name', 'text', 3467, 2260, 2260, 'admin', 308), 
    ('LN 2', 'Last Name', 'text', 3468, 2260, 2260, 'admin', 308), 
    ('Female', 'Gender', 'radio', 3466, 2260, 2260, 'admin', 308), 
    ('12', 'Age', 'number', 3469, 2260, 2260, 'admin', 308) 
) t([Answer],[QuestionText],[type],[QuestionID],[ResultID],[Action],[Username],[SurveyID])) 

SELECT 
    [ResultID], 
    [UserName], 
    [Action], 
    MAX(CASE WHEN c.[QuestionText] = 'First Name' THEN [Answer] END) as [First Name], 
    MAX(CASE WHEN c.[QuestionText] = 'Last Name' THEN [Answer] END) as [Last Name], 
    MAX(CASE WHEN c.[QuestionText] = 'Gender' THEN [Answer] END) as [Gender], 
    MAX(CASE WHEN c.[QuestionText] = 'Age' THEN [Answer] END) as [Age] 
FROM 
    cte c 
GROUP BY 
    [ResultID], 
    [UserName], 
    [Action] 


ResultID UserName Action  First Name Last Name Gender Age 
----------- -------- ----------- ---------- --------- ------ ------ 
2259  admin 2259  FN 1  LN 1  Male 12 
2260  admin 2260  FN 2  LN 2  Female 12