如何在SQL

时间:2018-01-08 16:10:14

标签: sql sql-server sql-server-2008 pivot

我一直在引用this question,但我的情况有点不同,所以我还没有弄明白。

我有一组看起来像这样的数据:

    --------------------------------------
    | Id | Answer|  Question   | EntryBy
    --------------------------------------
    | 1  |John   |Name?        | User1  |
    | 2  |2.4    |Raiting?     | User1  |
    | 3  |ZH1E4A |UserId?      | User1  |
    | 4  |Paul   |Name?        | User1  |
    | 5  |2.3    |Raiting?     | User1  |
    | 6  |Ron    |Name?        | User2  |
    | 7  |857685 |UserId?      | User2  |
    ----------------------------

我需要转动数据,使其结构如下:

    ----------------------------------------------------------
    | Category | Name? | Raiting? | UserId? | EntryBy |
    ----------------------------------------------------------
    | Category1| John  |   2.4    | ZH1E4A  | User1   |
    | Category1| Paul  |   2.3    |  NULL   | User1   |
    | Category1| Ron   |   NULL   |  857685 | User2   |

正如您所看到的,有多个“问题”,但它们并不总是有答案/值。我知道可以被问及/回答的问题的确切数量,所以我假设如果我使用CASE表达式可能有帮助吗?

注意:最后一个表中的“类别”列只是第一个类似于“EntryBy”的另一个值。我在引用的问题中尝试过枢轴方法,但我得到的结果并不正确。我也尝试了CASE语句但由于问题标题相同而导致错误。

2 个答案:

答案 0 :(得分:2)

2008年,我们失去sum()函数,但我们可以通过交叉应用模拟它来创建一个Grp指标。

这也假设ID是顺序的(有风险的)和Name?是组密钥。

另外,检查RAITING的拼写

另外,我不知道Category来自哪里

示例

Select [Name?]    = max(case when Question = 'Name?'   then Answer end)
      ,[Raiting?] = max(case when Question = 'Raiting?' then Answer end)
      ,[UserId?]  = max(case when Question = 'UserId?' then Answer end)
      ,[EntryBy?] = max([EntryBy])
 From (
        Select A.*
              ,B.Grp
         From YourTable A
         Cross Apply (Select Grp=count(*) from YourTable where Question='Name?' and ID<=A.ID) B
      ) A
 Group By Grp

<强>返回

Name?       Raiting?    UserId?  EntryBy?
John        2.4         ZH1E4A   User1
Paul        2.3         NULL     User1
Ron         NULL        857685   User2

答案 1 :(得分:1)

与John's相比,这只对该表进行了一次解析(或“值表表达式”),而得到2:

WITH VTE AS (
    SELECT *
    FROM (VALUES
                (1,'John  ','Name?   ','User1'),
                (2,'2.4   ','Raiting?','User1'),
                (3,'ZH1E4A','UserId? ','User1'),
                (4,'Paul  ','Name?   ','User1'),
                (5,'2.3   ','Raiting?','User1'),
                (6,'Ron   ','Name?   ','User2'),
                (7,'857685','UserId? ','User2'),
                (8,'Steve  ','Name?   ','User3'),
                (9,'2.5   ','Raiting?','User3'),
                (10,'Jane  ','Name?   ','User3'),
                (11,'GA18S1','UserId? ','User3'),
                (12,'2.3   ','Raiting?','User3'),
                (13,'ABH12D','UserId? ','User3')) V(ID, Answer, Question, EntryBy)),
Groups AS(
    SELECT *,
           ROW_NUMBER() OVER (ORDER BY ID ASC) -
           ROW_NUMBER() OVER (PARTITION BY CASE WHEN Question = 'Name?' THEN 0 ELSE 1 END ORDER BY ID ASC) AS Grp
    FROM VTE)
SELECT 'Category1' AS Category,
       MAX(CASE Question WHEN 'Name?' THEN Answer ELSE NULL END) AS [Name?],
       MAX(CASE Question WHEN 'Raiting?' THEN Answer ELSE NULL END) AS [Raiting?],
       MAX(CASE Question WHEN 'UserID?' THEN Answer ELSE NULL END) AS [UserID?],
       EntryBy
FROM Groups
GROUP BY CASE Grp WHEN 0 THEN Grp + 1 ELSE Grp END,
         EntryBy
ORDER BY CASE Grp WHEN 0 THEN Grp + 1 ELSE Grp END;

我还添加了一些额外的值来显示如果排序错误会发生什么。

结果集:

Category  Name?   Raiting? UserID? EntryBy
--------- ------- -------- ------- -------
Category1 John    2.4      ZH1E4A  User1
Category1 Paul    2.3      NULL    User1
Category1 Ron     NULL     857685  User2
Category1 Steve   2.5      NULL    User3
Category1 Jane    2.3      GA18S1  User3