简体   繁体   English

SQL Server Pivoting基于要定界的列

[英]SQL Server Pivoting based off of a column to be delimited

I'm using SQL Server Management Studio and I have a table of survey results for project managers and I'm aggregating by question/score at the project manager RepID level: 我正在使用SQL Server Management Studio,并且具有项目经理的调查结果表,并且在项目经理RepID级别按问题/得分进行RepID

SELECT Lower(A.RepID) as 'HHRepID' 
      ,  YEAR(A.ProjectEndDate)  AS 'Year'
      ,  MONTH(A.ProjectEndDate)  AS 'Month'
      ,  DATENAME(mm,A.ProjectEndDate) AS 'MonthName'
      , SUM(CASE WHEN A.SatisfactionWithCommunication >= 4 THEN 1 ELSE 0 END) as 'AgreeStronglyAgreeCommunicationCount' 
      , COUNT(A.SatisfactionWithCommunication) as 'CommunicationCount'
      , SUM(CASE WHEN A.InteractionConnectionWithClient >= 4 THEN 1 ELSE 0 END) as 'AgreeStronglyAgreeInteractionCount' 
      , COUNT(A.InteractionConnectionWithClient) as 'InteractionCount'
      , SUM(CASE WHEN A.OverallSatisfactionWithEngagement >= 4 THEN 1 ELSE 0 END) as 'AgreeStronglyAgreeOverallSatisfactionCount' 
      , COUNT(A.OverallSatisfactionWithEngagement) as 'OverallSatisfactionCount'
      , COUNT(A.ResponseID) as 'SurveysReturned'
      , 'SalesOps' as 'Grouping'
FROM 
   SurveyData.dbo.SalesSurvey as A with(nolock) 
WHERE 
   A.ResponseID IS NOT NULL AND A.IsExcludedFromReporting IS NULL
GROUP BY
   YEAR(A.ProjectEndDate), MONTH(A.ProjectEndDate), DATENAME(mm,A.ProjectEndDate), A.RepID
ORDER BY 
   A.RepID

The output would look something like this: 输出看起来像这样:

在此处输入图片说明

Everything is great. 一切都很棒。 Here's the problem. 这是问题所在。 For each response for a project manager, there could be multiple Project Assistants. 对于项目经理的每个答复,可能会有多个项目助理。 The project assistants for each project are aggregated (separated by ; ) in one column: 每个项目的项目助手都汇总在一栏中(用;分隔):

在此处输入图片说明

What I need to do is pivot/delimit these results so each projectassistantID will be 1 row with the same grouped data as if it was a project manager. 我需要做的是透视/定界这些结果,以便每个projectassistantID将是1行,并且具有相同的分组数据,就好像它是项目经理一样。 So for example, let's say that that row from the first screenshot had (HHRepID = jdoe) had 2 project assistants to it (call them Michael Matthews and Sarah Boyd): mmathews; 因此,例如,假设第一个屏幕截图的那一行(HHRepID = jdoe)有2个项目助手(分别称为Michael Matthews和Sarah Boyd):mmathews; sboyd. sboyd。 Via pivot/delimit, the output of the 2nd query would look like this: 通过数据透视/定界,第二个查询的输出将如下所示:

在此处输入图片说明

In the actual table, it's just 1 record. 在实际表中,只有1条记录。 But b/c there're multiple names in the ProjectAssistantID column, I need to pivot/delimit those out and essentially get the same results for each instance, just with ProjectAssistants rather than Project Managers. 但是b / c在ProjectAssistantID列中有多个名称,我需要透视/定界这些名称,并且基本上每个实例都获得相同的结果,仅使用ProjectAssistants而不是Project Managers。

I've been able to find some stuff on pivoting but this is pivoting based on delimiting values which adds an extra layer of complexity. 我已经找到了一些关于透视的东西,但这是基于分隔值的透视,这增加了额外的复杂性。 It's entirely possible that there could be only 1 project assistant per project or as many as 6. 每个项目可能只有一个项目助理或多达6个项目助手。

You can find several string split functions when you google for that, I will just assume this one which returns a table with one column named Item . 当您使用google时,您会发现几个字符串拆分函数,我只假设这个函数返回一个表,该表的一列名为Item

Then you can use cross apply as follows: 然后,您可以使用交叉申请,如下所示:

SELECT assist.Item as 'HHRepID' 
      ,  YEAR(A.ProjectEndDate)  AS 'Year'
      ,  MONTH(A.ProjectEndDate)  AS 'Month'
      ,  DATENAME(mm,A.ProjectEndDate) AS 'MonthName'
      , SUM(CASE WHEN A.SatisfactionWithCommunication >= 4 THEN 1 ELSE 0 END) as 'AgreeStronglyAgreeCommunicationCount' 
      , COUNT(A.SatisfactionWithCommunication) as 'CommunicationCount'
      , SUM(CASE WHEN A.InteractionConnectionWithClient >= 4 THEN 1 ELSE 0 END) as 'AgreeStronglyAgreeInteractionCount' 
      , COUNT(A.InteractionConnectionWithClient) as 'InteractionCount'
      , SUM(CASE WHEN A.OverallSatisfactionWithEngagement >= 4 THEN 1 ELSE 0 END) as 'AgreeStronglyAgreeOverallSatisfactionCount' 
      , COUNT(A.OverallSatisfactionWithEngagement) as 'OverallSatisfactionCount'
      , COUNT(A.ResponseID) as 'SurveysReturned'
      , 'SalesOps' as 'Grouping'
FROM 
   SurveyData.dbo.SalesSurvey as A with(nolock) 
   CROSS APPLY Split(Lower(A.RepID), ';') AS assist
WHERE 
   A.ResponseID IS NOT NULL AND A.IsExcludedFromReporting IS NULL
GROUP BY
   YEAR(A.ProjectEndDate), MONTH(A.ProjectEndDate), DATENAME(mm,A.ProjectEndDate), assist.Item
ORDER BY 
   assist.Item

For a strictly sql solution, you could use recursive cte to get your names split and then join it back to you query.. 对于严格的sql解决方案,您可以使用recursive cte拆分名称,然后join其重新join查询中。

Try the below query 试试下面的查询

DECLARE @col varchar(20)='a;b;c;g;y;u;i;o;p;';
WITH CTE as
(
SELECT SUBSTRING(@COL,CHARINDEX(';',@COL)+1, LEN(@COL)-CHARINDEX(';', @COL)) col
,SUBSTRING(@COL,0, CHARINDEX(';',@COL)) Split_Names
, 1 i

union ALL 
SELECT SUBSTRING(COL,CHARINDEX(';',COL)+1, LEN(COL)-CHARINDEX(';', COL)) col
,SUBSTRING(COL,0, CHARINDEX(';',COL)) Split_Names
, i+1
from CTE

WHERE CHARINDEX(';', col)>1
)
SELECT * FROM CTE 

You will need to use your column in place of @col and change the code to refer to your table in the first union statement. 您将需要使用列代替@col并更改代码以引用第一个union语句中的表。

Hope this helps... 希望这可以帮助...


So you would do something like this... 所以你会做这样的事情...

    WITH ProjectAssistants as
        (
        SELECT SUBSTRING(PROJECTASSISTANTID,CHARINDEX(';',PROJECTASSISTANTID)+1, LEN(PROJECTASSISTANTID)-CHARINDEX(';', PROJECTASSISTANTID)) col
        ,SUBSTRING(PROJECTASSISTANTID,0, CHARINDEX(';',PROJECTASSISTANTID)) Assistnames_Names
        , ProjectManagerID
        FROM YOUR_PROJECT_ASSISTANT_TABLE_NAME

        union ALL 
        SELECT SUBSTRING(COL,CHARINDEX(';',COL)+1, LEN(COL)-CHARINDEX(';', COL)) col
        ,SUBSTRING(COL,0, CHARINDEX(';',COL)) Assistnames_Names
        , ProjectManagerID
        from ProjectAssistants 

        WHERE CHARINDEX(';', col)>1
        )
        SELECT Lower(A.RepID) as 'HHRepID' 
      ,  YEAR(A.ProjectEndDate)  AS 'Year'
      ,  MONTH(A.ProjectEndDate)  AS 'Month'
      ,  DATENAME(mm,A.ProjectEndDate) AS 'MonthName'
      , SUM(CASE WHEN A.SatisfactionWithCommunication >= 4 THEN 1 ELSE 0 END) as 'AgreeStronglyAgreeCommunicationCount' 
      , COUNT(A.SatisfactionWithCommunication) as 'CommunicationCount'
      , SUM(CASE WHEN A.InteractionConnectionWithClient >= 4 THEN 1 ELSE 0 END) as 'AgreeStronglyAgreeInteractionCount' 
      , COUNT(A.InteractionConnectionWithClient) as 'InteractionCount'
      , SUM(CASE WHEN A.OverallSatisfactionWithEngagement >= 4 THEN 1 ELSE 0 END) as 'AgreeStronglyAgreeOverallSatisfactionCount' 
      , COUNT(A.OverallSatisfactionWithEngagement) as 'OverallSatisfactionCount'
      , COUNT(A.ResponseID) as 'SurveysReturned'
      , 'SalesOps' as 'Grouping'
FROM 
   SurveyData.dbo.SalesSurvey as A with(nolock) 
LEFT JOIN ProjectAssistants as B
   ON A.ProjectManagerID=B.ProjectManagerID
WHERE 
   A.ResponseID IS NOT NULL AND A.IsExcludedFromReporting IS NULL
GROUP BY
   YEAR(A.ProjectEndDate), MONTH(A.ProjectEndDate), DATENAME(mm,A.ProjectEndDate), A.RepID
ORDER BY 
   A.RepID

Assumptions: 假设:

  • Your Surveydata table has a ProjectManagerid column 您的Surveydata表具有一个ProjectManagerid列
  • Left Join-ed the ProjectManager CTE considering you still want to show data when there arent any assistants. 考虑到您仍然想在有任何助手时显示数据,请左加入ProjectManager CTE。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM