SQL数据透视表每行具有多个值

时间:2018-06-27 03:30:31

标签: sql sql-server tsql pivot

我正在尝试从查询中透视数据,该查询将在多列中包含日期时间字符串。基本查询如下:

SELECT jo.CandidateId
        , jo.CandidateName
        , jorh.JobOrderReferralStageHistoryId
        , jorh.JobOrderId
        , CONVERT(varchar, jorh.HistoryDate,3)+' '+ jorh.HistoryTime AS HistoryDateTime
        , jorh.StageName
FROM rpt.JobOrderReferralHistory jorh
    LEFT JOIN rpt.JobOrder jo ON jorh.JobOrderId = jo.JobOrderId
ORDER BY jorh.JobOrderId, jo.CandidateId, jorh.JobOrderReferralStageHistoryId

哪个会产生以下结果:

+-------------+--------------------------------+------------+------------------+--------------------------+
| CandidateId | JobOrderReferralStageHistoryId | JobOrderId |    HistoryDate   |        StageName         |
+-------------+--------------------------------+------------+------------------+--------------------------+
|   100027026 |                          71591 |  200005222 | 2018-06-18 19:02 | Applied New              |
|   100027026 |                          71601 |  200005222 | 2018-06-19 08:56 | Applied Existing         |
|   100027026 |                          71603 |  200005222 | 2018-06-19 08:56 | Telephone Screen         |
|   100027026 |                          71607 |  200005222 | 2018-06-19 09:35 | CV Sent to Client        |
|   100027026 |                          71625 |  200005222 | 2018-06-19 10:43 | Client Interview         |
|   100027026 |                          71662 |  200005222 | 2018-06-19 13:11 | Approved for Progression |
|   100027026 |                          71664 |  200005222 | 2018-06-19 13:11 | Testing/Screening        |
|   100027026 |                          71666 |  200005222 | 2018-06-19 13:11 | Pre-employment Medical   |
+-------------+--------------------------------+------------+------------------+--------------------------+

但是我需要这样看:

+------------+-------------+------------------+------------------+------------------+-------------------+------------------+--------------------------+-------------------+------------------------+
| JobOrderId | CandidateId |   Applied New    | Applied Existing | Telephone Screen | CV Sent to Client | Client Interview | Approved for Progression | Testing/Screening | Pre-employment Medical |
+------------+-------------+------------------+------------------+------------------+-------------------+------------------+--------------------------+-------------------+------------------------+
|  200005222 |   100027026 | 18/06/2018 19:02 | 19/06/2018 08:56 | 19/06/2018 08:56 | 19/06/2018 09:35  | 19/06/2018 10:43 | 19/06/2018 13:11         | 19/06/2018 13:11  | 19/06/2018 13:11       |
+------------+-------------+------------------+------------------+------------------+-------------------+------------------+--------------------------+-------------------+------------------------+

我尝试了以下方法,但它仅显示实现的最后阶段的日期时间字符串:

,MAX(CASE WHEN jor.Stage ='Database Search' THEN CONVERT(varchar, jorh.HistoryDate,3)+' '+ jorh.HistoryTime ELSE NULL END) AS DatabaseSearch
            ,MAX(CASE WHEN jor.Stage ='Applied New' THEN CONVERT(varchar, jorh.HistoryDate,3)+' '+ jorh.HistoryTime ELSE NULL END) AS AppliedNew

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:0)

我认为不需要连接表,使用一个表(JobOrderReferralHistory)如下所示:

SELECT MIN(jorh.JobOrderId) JobOrderId,
       MIN(jorh.CandidateId) CandidateId,
       MAX(CASE WHEN jorh.StageName ='Applied New'       THEN jorh.HistoryDate ELSE NULL END) AS "Applied New",
       MAX(CASE WHEN jorh.StageName ='Applied Existing'  THEN jorh.HistoryDate ELSE NULL END) AS "Applied Existing",
       MAX(CASE WHEN jorh.StageName ='Telephone Screen'  THEN jorh.HistoryDate ELSE NULL END) AS "Telephone Screen",
       MAX(CASE WHEN jorh.StageName ='CV Sent to Client' THEN jorh.HistoryDate ELSE NULL END) AS "CV Sent to Client",           
       MAX(CASE WHEN jorh.StageName ='Client Interview'  THEN jorh.HistoryDate ELSE NULL END) AS "Client Interview",
       MAX(CASE WHEN jorh.StageName ='Approved for Progression' THEN jorh.HistoryDate ELSE NULL END) AS "Approved for Progression",           
       MAX(CASE WHEN jorh.StageName ='Testing/Screening'        THEN jorh.HistoryDate ELSE NULL END) AS "Testing/Screening",
       MAX(CASE WHEN jorh.StageName ='Pre-employment Medical'   THEN jorh.HistoryDate ELSE NULL END) AS "Pre-employment Medical"       
  FROM JobOrderReferralHistory jorh;

SQL Fiddle Demo

答案 1 :(得分:0)

从结果集中开始,您可以像这样旋转数据:

declare @tmp table(CandidateId int, JobOrderReferralStageHistoryId int, JobOrderId int, HistoryDate datetime , StageName varchar(50))
insert into @tmp values
 (100027026, 71591, 200005222, '2018-06-18 19:02:00', 'Applied New') ,(100027026, 71601, 200005222, '2018-06-19 08:56:00', 'Applied Existing') ,(100027026, 71603, 200005222, '2018-06-19 08:56:00', 'Telephone Screen') ,(100027026, 71607, 200005222, '2018-06-19 09:35:00', 'CV Sent to Client') ,(100027026, 71625, 200005222, '2018-06-19 10:43:00', 'Client Interview') ,(100027026, 71662, 200005222, '2018-06-19 13:11:00', 'Approved for Progression') ,(100027026, 71664, 200005222, '2018-06-19 13:11:00', 'Testing/Screening') ,(100027026, 71666, 200005222, '2018-06-19 13:11:00', 'Pre-employment Medical')

select *
from 
( 
    select JobOrderId,  CandidateId ,HistoryDate,StageName
    from @tmp 
) src 
pivot 
( 
    max(HistoryDate) 
    for StageName in ([Applied New], [Applied Existing], [Telephone Screen], [CV Sent to Client], [Client Interview], [Approved for Progression], [Testing/Screening], [Pre-employment Medical]) 
) piv 

结果:

enter image description here

答案 2 :(得分:0)

我认为您在工作订单表中将有多个候选人。您可以尝试以下操作:

select 
    jo.JobOrderId, 
    jo.CandidateId,
    CONVERT(varchar, jorh1.HistoryDate)+' '+ Convert(varchar,jorh1.HistoryTime) AS "Applied new",
    CONVERT(varchar, jorh2.HistoryDate)+' '+ Convert(varchar,jorh2.HistoryTime) AS "Applied Existing",
    CONVERT(varchar, jorh3.HistoryDate)+' '+ Convert(varchar,jorh3.HistoryTime) AS "Telephone Screen",
    CONVERT(varchar, jorh4.HistoryDate)+' '+ Convert(varchar,jorh4.HistoryTime) AS "CV Sent to Client",
    CONVERT(varchar, jorh5.HistoryDate)+' '+ Convert(varchar,jorh5.HistoryTime) AS "Client Interview",
    CONVERT(varchar, jorh6.HistoryDate)+' '+ Convert(varchar,jorh6.HistoryTime) AS "Approved for Progression",
    CONVERT(varchar, jorh7.HistoryDate)+' '+ Convert(varchar,jorh7.HistoryTime) AS "Testing/Screening",
    CONVERT(varchar, jorh8.HistoryDate)+' '+ Convert(varchar,jorh8.HistoryTime) AS "Pre-employment Medical"
from
    JobOrder jo
left outer join 
    JobOrderReferralHistory jorh1
    on jorh1.JobOrderId = jo.JobOrderId And jorh1.stagename = 'Applied New'
left outer join 
    JobOrderReferralHistory jorh2
    on jorh2.JobOrderId = jo.JobOrderId And jorh2.stagename = 'Applied Existing'
left outer join 
    JobOrderReferralHistory jorh3
    on jorh3.JobOrderId = jo.JobOrderId And jorh3.stagename = 'Telephone Screen'
left outer join 
    JobOrderReferralHistory jorh4
    on jorh4.JobOrderId = jo.JobOrderId And jorh4.stagename = 'CV Sent to Client'
left outer join 
    JobOrderReferralHistory jorh5
    on jorh5.JobOrderId = jo.JobOrderId And jorh5.stagename = 'Client Interview'
left outer join 
    JobOrderReferralHistory jorh6
    on jorh6.JobOrderId = jo.JobOrderId And jorh6.stagename = 'Approved for Progression'
left outer join 
    JobOrderReferralHistory jorh7
    on jorh7.JobOrderId = jo.JobOrderId And jorh7.stagename = 'Testing/Screening'
left outer join 
    JobOrderReferralHistory jorh8
    on jorh8.JobOrderId = jo.JobOrderId And jorh8.stagename = 'Pre-employment Medical'

SQL Fiddle Demo