Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.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 2012 - Fatal编程技术网

Sql 如何基于另一列在同一表列中进行透视查询

Sql 如何基于另一列在同一表列中进行透视查询,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有表[Application].[ApplicationDetails],其中有3列 ID | [QuestionId] | [Answer] 1 | 106 | YES I HAVE 2 | 106 | ONLY SIMAB HAVE 3 | 107 | ORANGES WERE SOUR 4 | 107

我有表[Application].[ApplicationDetails],其中有3列

      ID   |  [QuestionId]   |   [Answer]
       1   |   106           |   YES I HAVE
       2   |   106           |   ONLY SIMAB HAVE
       3   |   107           |   ORANGES WERE SOUR
       4   |   107           |   GRAPES SOUR
       5   |   108           |   ALEIN CENTER 
       6   |   106           |   no one
我需要一个pivot查询来显示我的答案数据,如

     QuestionId
Answers
范例

  106              108 
  YES I HAVE       ALEIN CENTER
  ONLY SIMAB HAVE
继续我要做的事

      WITH cte AS (
           SELECT [QuestionId] as [Quest],
             [Answer] as [Answer] 

      FROM  [Application].[ApplicationDetails]

      )

                SELECT [Answer] ,[Quest]
                FROM
                (
                SELECT [Quest]  , [Answer]

                FROM cte
                          ) d
                pivot
                (
                [Answer]  in [Quest]
      ) piv
        ORDER BY [Quest];

但是这个不起作用的关键字在

中是不正确的,这应该会给你想要的结果

SELECT [106], [107]
FROM (
    SELECT QuestionId, Answer, ROW_NUMBER() OVER (PARTITION BY QuestionId ORDER BY Answer) r
    FROM [dbo].[ApplicationDetails]
) t
PIVOT(MAX(Answer) FOR QuestionId IN ([106], [107])) AS p
编辑动态SQL


这将为您提供所需的结果,但是当您的选择中有ID时,如果您的问题ID与文本不匹配,则会出现空值

DECLARE @myt TABLE (
 ID int, QuestionID int, Answer nvarchar(50)
  )

  insert into @myt
  values 

   (1,   106,'YES I HAVE'),
   (2,   106,'ONLY SIMAB HAVE'),
   (3,   107,'ORANGES WERE SOUR'),
   (4,   107,'GRAPES SOUR'),
   (5,   108,'ALEIN CENTER'),
   (6,   106,'no one')



   select [106],[107],[108]
   from @myt
   PIVOT 
   (Max(Answer) FOR QUESTIONID in ([106],[107],[108])
   ) as p;
如果您希望它位于具有新ID的同一行上

DECLARE @myt TABLE (
 ID int, QuestionID int, Answer nvarchar(50)
 )

   insert into @myt
 values 

   (1,   106,'YES I HAVE'),
   (2,   106,'ONLY SIMAB HAVE'),
   (3,   107,'ORANGES WERE SOUR'),
   (4,   107,'GRAPES SOUR'),
   (5,   108,'ALEIN CENTER'),
   (6,   106,'no one')



  select * from (
   select QuestionID,Answer,ROW_NUMBER() over(PARTITION by QuestionID order by answer) as rn
   from @myt
   )x
   PIVOT 
   (Max(Answer) FOR QuestionID in ([106],[107],[108])
   ) as p
使用动态SQL编辑更新

具有动态查询和自制ID的结果

以下是简短的动态轴心方式:


只需添加您所需的questionId,您将根据questionId得到结果

示例数据创建

IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t;

IF OBJECT_ID('tempdb..#Result') IS NOT NULL
DROP TABLE #Result;

GO

;With cte(ID,[QuestionId],[Answer])
AS
(
SELECT 1,106,'YES I HAVE'       UNION ALL
SELECT 2,106,'ONLY SIMAB HAVE'  UNION ALL
SELECT 3,107,'ORANGES WERE SOUR'UNION ALL
SELECT 4,107,'GRAPES SOUR'      UNION ALL
SELECT 5,108,'ALEIN CENTER'     UNION ALL
SELECT 6,106,'no one'
)
SELECT *  INTO #t FROM cte
在下面的变量中添加所需的问号

DECLARE @QuestinID VARCHAR(100)='106,107,108'-- Add Required QuestionId's

DECLARE @GetQuestion TABLE (QuestionID VARCHAR(100))
    INSERT INTO @GetQuestion
    SELECT @QuestinID


    SELECT * INTO #Result 
    FROM #t WHERE QuestionID IN(SELECT CAST(Split.a.value('.','nvarchar(1000)') AS INT) AS QuestionID  FROM
    (
    SELECT 
    CAST('<S>'+REPLACE(QuestionID,',','</S><S>')+'</S>' AS XML ) AS QuestionID 
    FROM @GetQuestion 
    )AS A
    CROSS APPLY QuestionID.nodes('S') AS Split(a))
    ORDER BY QuestionID


    DECLARE @Sql nvarchar(max),@DyColm nvarchar(max)

    SELECT @DyColm=STUFF((SELECT DISTINCT ', '+ QUOTENAME(CAST(QuestionID AS VARCHAR(10))) FROM #Result FOR XML PATH ('')),1,2,'')



    SET @Sql='
    SELECT '+@DyColm+' FROm
    (
    SELECT * FRom #Result
    )AS Src
     PIVOT
     (
     MAX([Answer]) FOR QuestionID IN ('+@DyColm+')
     )AS Pvt
     '

     PRINT @Sql
     EXEC(@Sql)
     SET NOCOUNT OFF

我正在使用的SQL SERVER如果它们没有相同的id,则不能将它们放在同一行。问题id 106下有106个答案,107下有107个答案。问题id作为列,答案作为行。不仅2个id是106或107,而且数据量大,所以我们应该尝试所有id。然后,您应该使用动态SQL查询。应该是什么样的?您能帮助我做到这一点吗选择从[Application].[ApplicationDetails]将[QuestionId]选为INT,从[Application].[ApplicationDetails]将[QuestionId]选为测试,从[Application].[ApplicationDetails]选为答案,从[QuestionId]按分区按排数排序,从[ApplicationDetails]选为答案rt PivotMaxResponse测试中的问题ID为pbut,将数据类型nvarchar转换为int.Msg 473,16级,状态1时出错,第8行PIVOT运算符中提供了不正确的值测试。我告诉数据示例我有大量数据这些是硬编码的id,但我需要有效的解决方案,而不是硬编码的,因为数据很大。获取id首先选择从[Application]中选择CAST[QuestionId]作为INT。[ApplicationDetails]同样,这不是你在提问时要问的问题。如果您想在多个值上求解它,那么应该使列选择动态化
DECLARE @Str NVARCHAR(MAX);
DECLARE @Str2 NVARCHAR(MAX);
SELECT @Str = STUFF(
                   (
                       SELECT DISTINCT
                              ','+QUOTENAME(QuestionID)
                       FROM <table_name> FOR XML PATH('')
                   ), 1, 1, '');

                  -- PRINT @Str

SET @str2 = N'select * from (
   select QuestionID,Answer,ROW_NUMBER() over(PARTITION by QuestionID order by answer) as rn
   from <table_name>
   )x
   PIVOT 
   (Max(Answer) FOR QuestionID in ('+@Str+')
   ) as p';
--PRINT @Str2;
EXEC (@Str2);
rn  106             107                 108
1   YES I HAVE      GRAPES SOUR         ALEIN CENTER    
2   no one          ORANGES WERE SOUR   NULL
3   ONLY SIMAB HAVE NULL                NULL
IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t;

IF OBJECT_ID('tempdb..#Result') IS NOT NULL
DROP TABLE #Result;

GO

;With cte(ID,[QuestionId],[Answer])
AS
(
SELECT 1,106,'YES I HAVE'       UNION ALL
SELECT 2,106,'ONLY SIMAB HAVE'  UNION ALL
SELECT 3,107,'ORANGES WERE SOUR'UNION ALL
SELECT 4,107,'GRAPES SOUR'      UNION ALL
SELECT 5,108,'ALEIN CENTER'     UNION ALL
SELECT 6,106,'no one'
)
SELECT *  INTO #t FROM cte
DECLARE @QuestinID VARCHAR(100)='106,107,108'-- Add Required QuestionId's

DECLARE @GetQuestion TABLE (QuestionID VARCHAR(100))
    INSERT INTO @GetQuestion
    SELECT @QuestinID


    SELECT * INTO #Result 
    FROM #t WHERE QuestionID IN(SELECT CAST(Split.a.value('.','nvarchar(1000)') AS INT) AS QuestionID  FROM
    (
    SELECT 
    CAST('<S>'+REPLACE(QuestionID,',','</S><S>')+'</S>' AS XML ) AS QuestionID 
    FROM @GetQuestion 
    )AS A
    CROSS APPLY QuestionID.nodes('S') AS Split(a))
    ORDER BY QuestionID


    DECLARE @Sql nvarchar(max),@DyColm nvarchar(max)

    SELECT @DyColm=STUFF((SELECT DISTINCT ', '+ QUOTENAME(CAST(QuestionID AS VARCHAR(10))) FROM #Result FOR XML PATH ('')),1,2,'')



    SET @Sql='
    SELECT '+@DyColm+' FROm
    (
    SELECT * FRom #Result
    )AS Src
     PIVOT
     (
     MAX([Answer]) FOR QuestionID IN ('+@DyColm+')
     )AS Pvt
     '

     PRINT @Sql
     EXEC(@Sql)
     SET NOCOUNT OFF