2017-07-25 79 views
-1

我想的cols轉換爲行,以適應格式的圖像 行這是我的查詢:轉換列使用數據透視

Select dt1.Year,dt1.oneyearret as '1-Year Retention',dt2.twoyearret as '2-Year Retention',dt4.fouryeargrad as '4-Year Graduation Rate',dt5.fiveyeargrad as '5-Year Graduation Rate',dt6.sixyeargrad as '6-Year Graduation Rate' from 
(select case WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2015' then '2015' WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2016' then '2016' else (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) end as 'Year', 
            cast(convert(varchar,(Convert(Money,SUM(rg.RET1_FF),1)/Convert(Money,SUM(rg.COHORT_COUNT),1))*100,1) as numeric(10,1)) as oneyearret   
            from vw_Retention_Graduation_F rg 
            inner join dim_Time t 
            on rg.TIME_KEY = t.TIME_KEY 
            inner join dim_Part_Full pf 
            on rg.PART_FULL_KEY=pf.PART_FULL_KEY 
            inner join dim_Student_Level sl 
            on rg.STUDENT_LEVEL_KEY=SL.STUDENT_LEVEL_KEY 
            inner join dim_Student_Population sp 
            on rg.STUDENT_POPULATION_KEY=sp.STUDENT_POPULATION_KEY 
            inner join dim_College c 
            on rg.COLLEGE_KEY = c.COLLEGE_KEY 
            WHERE t.ACADEMIC_PERIOD between 201527 and 201627 
            AND pf.PART_FULL = 'F' 
            AND sl.STUDENT_LEVEL = 'UG' 
            AND sp.STUDENT_POPULATION = 'N' 
            GROUP BY (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4)))) dt1 inner join 
(select case WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2014' then '2015' WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2015' then '2016' else (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) end as 'Year', 
            cast(convert(varchar,(Convert(Money,SUM(rg.RET2_FF),1)/Convert(Money,SUM(rg.COHORT_COUNT),1))*100,1) as numeric(10,1)) as twoyearret   
            from vw_Retention_Graduation_F rg 
            inner join dim_Time t 
            on rg.TIME_KEY = t.TIME_KEY 
            inner join dim_Part_Full pf 
            on rg.PART_FULL_KEY=pf.PART_FULL_KEY 
            inner join dim_Student_Level sl 
            on rg.STUDENT_LEVEL_KEY=SL.STUDENT_LEVEL_KEY 
            inner join dim_Student_Population sp 
            on rg.STUDENT_POPULATION_KEY=sp.STUDENT_POPULATION_KEY 
            inner join dim_College c 
            on rg.COLLEGE_KEY = c.COLLEGE_KEY 
            WHERE t.ACADEMIC_PERIOD between 201427 and 201527 
            AND pf.PART_FULL = 'F' 
            AND sl.STUDENT_LEVEL = 'UG' 
            AND sp.STUDENT_POPULATION = 'N' 
            GROUP BY (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4)))) dt2 on dt1.Year = dt2.year 
            inner join 
(select case WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2012' then '2015' WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2013' then '2016' else (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) end as 'Year', 
            cast(convert(varchar,(Convert(Money,SUM(rg.GRAD4_FF),1)/Convert(Money,SUM(rg.COHORT_COUNT),1))*100,1) as numeric(10,1)) as fouryeargrad   
            from vw_Retention_Graduation_F rg 
            inner join dim_Time t 
            on rg.TIME_KEY = t.TIME_KEY 
            inner join dim_Part_Full pf 
            on rg.PART_FULL_KEY=pf.PART_FULL_KEY 
            inner join dim_Student_Level sl 
            on rg.STUDENT_LEVEL_KEY=SL.STUDENT_LEVEL_KEY 
            inner join dim_Student_Population sp 
            on rg.STUDENT_POPULATION_KEY=sp.STUDENT_POPULATION_KEY 
            inner join dim_College c 
            on rg.COLLEGE_KEY = c.COLLEGE_KEY 
            WHERE t.ACADEMIC_PERIOD between 201227 and 201327 
            AND pf.PART_FULL = 'F' 
            AND sl.STUDENT_LEVEL = 'UG' 
            AND sp.STUDENT_POPULATION = 'N' 
            GROUP BY (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4)))) dt4 on dt2.Year = dt4.year 
            inner join 
(select case WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2011' then '2015' WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2012' then '2016' else (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) end as 'Year', 
            cast(convert(varchar,(Convert(Money,SUM(rg.GRAD5_FF),1)/Convert(Money,SUM(rg.COHORT_COUNT),1))*100,1) as numeric(10,1)) as fiveyeargrad   
            from vw_Retention_Graduation_F rg 
            inner join dim_Time t 
            on rg.TIME_KEY = t.TIME_KEY 
            inner join dim_Part_Full pf 
            on rg.PART_FULL_KEY=pf.PART_FULL_KEY 
            inner join dim_Student_Level sl 
            on rg.STUDENT_LEVEL_KEY=SL.STUDENT_LEVEL_KEY 
            inner join dim_Student_Population sp 
            on rg.STUDENT_POPULATION_KEY=sp.STUDENT_POPULATION_KEY 
            inner join dim_College c 
            on rg.COLLEGE_KEY = c.COLLEGE_KEY 
            WHERE t.ACADEMIC_PERIOD between 201127 and 201227 
            AND pf.PART_FULL = 'F' 
            AND sl.STUDENT_LEVEL = 'UG' 
            AND sp.STUDENT_POPULATION = 'N' 
            GROUP BY (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4)))) dt5 on dt4.Year = dt5.year 
            inner join 
(select case WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2010' then '2015' WHEN (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) ='2011' then '2016' else (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4))) end as 'Year', 
            cast(convert(varchar,(Convert(Money,SUM(rg.GRAD6_FF),1)/Convert(Money,SUM(rg.COHORT_COUNT),1))*100,1) as numeric(10,1)) as sixyeargrad   
            from vw_Retention_Graduation_F rg 
            inner join dim_Time t 
            on rg.TIME_KEY = t.TIME_KEY 
            inner join dim_Part_Full pf 
            on rg.PART_FULL_KEY=pf.PART_FULL_KEY 
            inner join dim_Student_Level sl 
            on rg.STUDENT_LEVEL_KEY=SL.STUDENT_LEVEL_KEY 
            inner join dim_Student_Population sp 
            on rg.STUDENT_POPULATION_KEY=sp.STUDENT_POPULATION_KEY 
            inner join dim_College c 
            on rg.COLLEGE_KEY = c.COLLEGE_KEY 
            WHERE t.ACADEMIC_PERIOD between 201027 and 201127 
            AND pf.PART_FULL = 'F' 
            AND sl.STUDENT_LEVEL = 'UG' 
            AND sp.STUDENT_POPULATION = 'N' 
            GROUP BY (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD_all,1,4)))) dt6 on dt5.Year = dt6.year 

電流輸出: ![enter image description here

所需的輸出: ![https://i.stack.imgur.com/FID9g.png

+4

哇查詢是嚴重難看。一些格式化將把文本牆變成不會讓其他人想要自殺的東西。 –

+0

如果你可以讀它很好,否則不打擾。 –

+4

所以我幫你格式化你的文章,你告訴我不要打擾。對於那些試圖幫助你的人來說,這不是一種很好的態度。 –

回答

1

用較短的代碼替換冗長的SQL代碼後,只需生成示例數據,就可以實現實際的「轉置」操作這樣的:

create table tbl (yr int, y1ret float, y2ret float, y4grad float, y5grad float, y6grad float); 
insert into tbl VALUES (2015, 83.5, 71.4, 34.8, 54.7, 59.9), (2016, 83.6, 73.8, 33.8, 53.6, 60); 

select * from (
    select yr, col, value 
    from tbl 
    unpivot 
    (
    value 
    for col in (y1ret, y2ret, y4grad, y5grad, y6grad) 
) unpiv 

) src 
pivot 
(
    max(value) 
    for yr in ([2015], [2016]) 
) piv 

這是當然的原始解決方案的適應這裏介紹:SQL transpose full table
正在運行的演示可以在這裏找到:http://rextester.com/CNYR30557

在大多數應用中,更簡單,更快速地做這種在接收環境中進行操作,即在使用PHP的後端或使用JavaScript的前端。

編輯

爲了滿足您長時間的SQL代碼到這一點,你可以這樣做:

;WITH tbl AS (-- YOUR CODE GOES HERE -- 
) 
select * from (
    select yr, col, value 
    from tbl 
    unpivot 
    (
    value 
    for col in (y1ret, y2ret, y4grad, y5grad, y6grad) 
) unpiv 

) src 
pivot 
(
    max(value) 
    for yr in ([2015], [2016]) 
) piv 
+0

感謝您的這一點,但我沒有權限創建表。 –

+0

你不需要創建表格。那只是一個佔位符。如果你把你的代碼放到「公用表表達式」中,那麼你可以從那裏運行整個事情。 「CTE」的行爲就像一個視圖或表格。 – cars10m

+0

啊!萬分感謝! –