我几乎完成了使用多个pivot非聚合函数的MS SQL查询,无法生成所需的结果。 任何人都可以帮助我,不知道我错过了什么? 如果有更简单的解决方案,请随时分享。
非常感谢任何帮助!
SQL小提琴
答案 0 :(得分:1)
您的查询是硬编码 PIVOT ,最多10列。在我看来,我将您的查询重新制作为更具可读性的形式。
<强> LiveDemo 强>
WITH cte AS
(
SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY policyID ORDER BY policyID)
FROM #tbl_policy_client_details
)
SELECT policyID
,[No of travellers] = COUNT(*)
,[Traveller 1 - Age] = MAX(CASE WHEN rn = 1 THEN Age END)
,[Name 1] = MAX(CASE WHEN rn = 1 THEN FirstName END)
,[Surname 1] = MAX(CASE WHEN rn = 1 THEN Surname END)
,[Type Condition 1] = MAX(CASE WHEN rn = 1 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
,[Traveller 2 - Age] = MAX(CASE WHEN rn = 2 THEN Age END)
,[Name 2] = MAX(CASE WHEN rn = 2 THEN FirstName END)
,[Surname 2] = MAX(CASE WHEN rn = 2 THEN Surname END)
,[Type Condition 2] = MAX(CASE WHEN rn = 2 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
,[Traveller 3 - Age] = MAX(CASE WHEN rn = 3 THEN Age END)
,[Name 3] = MAX(CASE WHEN rn = 3 THEN FirstName END)
,[Surname 3] = MAX(CASE WHEN rn = 3 THEN Surname END)
,[Type Condition 3] = MAX(CASE WHEN rn = 3 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
,[Traveller 4 - Age] = MAX(CASE WHEN rn = 4 THEN Age END)
,[Name 4] = MAX(CASE WHEN rn = 4 THEN FirstName END)
,[Surname 4] = MAX(CASE WHEN rn = 4 THEN Surname END)
,[Type Condition 4] = MAX(CASE WHEN rn = 4 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
,[Traveller 5 - Age] = MAX(CASE WHEN rn = 5 THEN Age END)
,[Name 5] = MAX(CASE WHEN rn = 5 THEN FirstName END)
,[Surname 5] = MAX(CASE WHEN rn = 5 THEN Surname END)
,[Type Condition 5] = MAX(CASE WHEN rn = 5 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
,[Traveller6 - Age] = MAX(CASE WHEN rn = 6 THEN Age END)
,[Name 6] = MAX(CASE WHEN rn = 6 THEN FirstName END)
,[Surname 6] = MAX(CASE WHEN rn = 6 THEN Surname END)
,[Type Condition 6] = MAX(CASE WHEN rn = 6 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
,[Traveller 7 - Age] = MAX(CASE WHEN rn = 7 THEN Age END)
,[Name 7] = MAX(CASE WHEN rn = 7 THEN FirstName END)
,[Surname 7] = MAX(CASE WHEN rn = 7 THEN Surname END)
,[Type Condition 7] = MAX(CASE WHEN rn = 7 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
,[Traveller 8 - Age] = MAX(CASE WHEN rn = 8 THEN Age END)
,[Name 8] = MAX(CASE WHEN rn = 8 THEN FirstName END)
,[Surname 8] = MAX(CASE WHEN rn = 8 THEN Surname END)
,[Type Condition 8] = MAX(CASE WHEN rn = 8 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
,[Traveller 9 - Age] = MAX(CASE WHEN rn = 9 THEN Age END)
,[Name 9] = MAX(CASE WHEN rn = 9 THEN FirstName END)
,[Surname 9] = MAX(CASE WHEN rn = 9 THEN Surname END)
,[Type Condition 9] = MAX(CASE WHEN rn = 9 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
,[Traveller 10 - Age] = MAX(CASE WHEN rn = 10 THEN Age END)
,[Name 10] = MAX(CASE WHEN rn = 10 THEN FirstName END)
,[Surname 10] = MAX(CASE WHEN rn = 10 THEN Surname END)
,[Type Condition 10] = MAX(CASE WHEN rn = 10 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
FROM cte
GROUP BY policyID
工作原理:
非常简单GROUP BY
,其中有多列,每组最多可容纳10个客户。就像您的PIVOT
。
SELECT policyID
,[No of travellers] = COUNT(*)
,[Traveller 1 - Age] = MAX(CASE WHEN rn = 1 THEN Age END)
,[Name 1] = MAX(CASE WHEN rn = 1 THEN FirstName END)
,[Surname 1] = MAX(CASE WHEN rn = 1 THEN Surname END)
,[Type Condition 1] = MAX(CASE WHEN rn = 1 THEN IIF(TypeID IS NULL , 'No', 'Yes') END)
FROM cte
GROUP BY policyID;
修改强>
您的初始查询无效的原因是您使用字符串文字而不是名称列。改为使用:
With client_details AS
(
SELECT cd.*,
CASE WHEN TypeID IS NULL THEN 'No' Else 'Yes' END [TypeResult]
,'Age'+CONVERT(VARCHAR(10),ROW_NUMBER()OVER(PARTITION BY cd.PolicyID ORDER BY TravellerID DESC)) AS [Ages]
,'name'+CONVERT(VARCHAR(10),ROW_NUMBER()OVER(PARTITION BY cd.PolicyID ORDER BY TravellerID DESC))AS [Name]
,'surname'+CONVERT(VARCHAR(10),ROW_NUMBER()OVER(PARTITION BY cd.PolicyID ORDER BY TravellerID DESC)) AS [Surnames],
'Type'+CONVERT(VARCHAR(10),ROW_NUMBER()OVER(PARTITION BY cd.PolicyID ORDER BY TravellerID DESC)) AS [Type]
FROM tbl_policy_client_details cd
WHERE cd.PolicyID IS not NULL)
SELECT
policyID
,COUNT(PolicyID)[No of travellers]
,MAX(Age1) [Traveller 1 - Age],MAX(Name1) [Name 1],MAX(Surname1) [Surname 1],MAX(Type1) [Type Condition 1]
,MAX(Age2) [Traveller 2 - Age],MAX(Name2) [Name 2],MAX(Surname1) [Surname 2],MAX(Type2) [Type Condition 2]
,MAX(Age3) [Traveller 3 - Age],MAX(Name3) [Name 3],MAX(Surname1) [Surname 3],MAX(Type3) [Type Condition 3]
,MAX(Age4) [Traveller 4 - Age],MAX(Name4) [Name 4],MAX(Surname1) [Surname 4],MAX(Type4) [Type Condition 4]
,MAX(Age5) [Traveller 5 - Age],MAX(Name5) [Name 5],MAX(Surname1) [Surname 5],MAX(Type5) [Type Condition 5]
-- ...
FROM
(SELECT cd.*
FROM client_details cd) p
PIVOT(MAX(Age)FOR Ages IN ([Age1],[Age2],[Age3],[Age4],[Age5],[Age6],[Age7],[Age8],[Age9],[Age10])) AS pvt
PIVOT (MAX(Firstname)
FOR Name IN ([Name1],[Name2],[Name3],[Name4],[Name5],[Name6],[Name7],[Name8],[Name9],[Name10])) AS Pivot1
PIVOT (MAX(Surnames)
FOR Surname IN ([Surname1],[Surname2],[Surname3],[Surname4],[Surname5],[Surname6],[Surname7],[Surname8],[Surname9],[Surname10])) AS Pivot2
PIVOT (MAX(TypeResult)
FOR Type IN ([Type1],[Type2],[Type3],[Type4],[Type5],[Type6],[Type7],[Type8],[Type9],[Type10])) AS Pivot3
GROUP BY Pivot3.policyID;
<强> SqlFiddleDemo 强>