非聚合多个支点 - 卡住了MS SQL查询

时间:2015-10-16 16:19:04

标签: sql sql-server tsql pivot

我几乎完成了使用多个pivot非聚合函数的MS SQL查询,无法生成所需的结果。 任何人都可以帮助我,不知道我错过了什么? 如果有更简单的解决方案,请随时分享。

非常感谢任何帮助!

SQL小提琴

http://www.sqlfiddle.com/#!3/0103d/1/0

Pivot query Issue

1 个答案:

答案 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