Sql 如何基于另一列在同一表列中进行透视查询
我有表[Application].[ApplicationDetails],其中有3列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
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