Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQL中将行转换为列_Sql_Sql Server_Sql Server 2008_Pivot - Fatal编程技术网

如何在SQL中将行转换为列

如何在SQL中将行转换为列,sql,sql-server,sql-server-2008,pivot,Sql,Sql Server,Sql Server 2008,Pivot,我参考了很多,但我的案例有点不同,所以我还没有完全弄明白 我有一组数据如下所示: -------------------------------------- | Id | Answer| Question | EntryBy -------------------------------------- | 1 |John |Name? | User1 | | 2 |2.4 |Raiting? | User1

我参考了很多,但我的案例有点不同,所以我还没有完全弄明白

我有一组数据如下所示:

    --------------------------------------
    | 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   |
如您所见,有多个“问题”,但它们并不总是有答案/价值。我知道可能被问/回答的问题的确切数量,所以我假设如果我使用案例表达,这可能会有所帮助


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

2008年,我们失去了sum()over函数,但我们可以通过交叉应用来模拟它以创建Grp指示器

这还假设ID是连续的(有风险的),名称是?是组密钥

另外,检查RAITING的拼写

另外,我不知道这个类别是从哪里来的

示例

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

与John的表(或“值表表达式”)相比,这只对该表(或“值表表达式”)进行了一次单独的解析,John的表(或“值表表达式”)进行了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

你如何判断哪些数据与哪些相关?例如,
John
2.4
结合在一起是什么意思?为什么不
John
2.3
?我看不到任何团体标识符的孩子。“不正确”是非常没有帮助的。请显示您尝试过的代码、得到的结果、预期的结果等。是否需要将数据透视到列中的固定值列表?(总是
'Name?
'Raiting?
'UserId?
'EntryBy'
?)是否有其他字段可用于确定行1-3聚合到一个输出行,然后行4-5聚合到下一个输出行,以此类推?或者您仅仅是基于id必须是连续的并且
'Name?
总是排在第一位这一事实来推断这一点吗?(这是一个非常弱/危险的假设,例如,标识列不能保证是顺序的和按设定的顺序排列。)@Larnu-好问题。唯一将这些项联系在一起的是ID序列。要真正知道哪些数据应该分组。。。我能想到的唯一方法是将ID序列、类别和EntryBy组合起来我相信这是可行的,但是在大型数据集上,三角形连接在交叉应用中会很昂贵:(我第一次尝试就实现了这一点!因为数据集不是很大,所以我不太关心效率。@JohnnyGamez很高兴它能帮上忙。另外(对OP来说)请注意,Steve的
[UserID?]的值为
NULL
。这是一个排序错误的示例,Jane似乎回答了问题
UserID?
两次。在这种情况下,只返回
MAX
值(这很可能是错误的值(Jane应该有
[UserID?]
ABH12D
)。如果此排序不可信,则解决方案也不可信(但如果我们没有可靠的序列/组定义,我没有备用解决方案)。将
EntryBy
添加到分区中可能会使假设更安全。(似乎多个数据输入用户同时为不同的“实体”按顺序输入数据).来自不同EntryBy用户的实体可以交错?但不是来自同一EntryBy用户?如果是,按OP评论的时间戳排序-可能-比使用id更好?)也许可以,@MatBailie.OP,但是,目前已经从他们的样本数据中忽略了这一点,所以我不想假设这些数据可能是什么样子。我担心的是,
EntryBy
列可能会遇到同样的问题(特别是如果它使用的默认值是
GETDATE()
或类似值)。值得让OP进行测试,然后,如果事情看起来不对劲,则提供进一步的样本,并包含未返回预期结果集的数据。
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