2017-10-13 46 views
0

脚本(下面列出)给出了结果(见截图01)Screenshot 01 但结果需要显示为(请参阅screenshot02)Screenshot02如何将行转换为TSQL中的列?

work_date中的日期(请参见屏幕截图01)需要显示为单个日期列,并且work_hour中的小时数(请参阅屏幕截图01)需要在各个日期列下显示。

DECLARE @01_STARTDATE VARCHAR(100); 
DECLARE @02_ENDDATE VARCHAR(100); 
DECLARE @STAFF INT; 

SET @01_STARTDATE = '2017-07-06'; 
SET @02_ENDDATE = '2017-07-10'; 
SET @STAFF = 8; 

SELECT 
    @01_STARTDATE + ' - ' + @02_ENDDATE AS [Date Range], 
    SU.FIRST_NAME + ' ' + SU.LAST_NAME AS Staff, 
    f.FACILITY_NAME AS Site_Name, 
    P.PRJ_PROJECT_NAME AS Project_Name, 
    R.PROJECT_TYPE_NAME AS Project_Type_Brownfield, 
    '' AS Project_Type_VRP, 
    st.work_hour, st.work_date 
FROM 
    FAC_FACILITY AS f 
INNER JOIN 
    GOV.PRJ_PROJECT AS P ON f.FACILITY_RID = p.FACILITY_RID 
INNER JOIN 
    GOV.SYS_TIME_LOG AS ST ON ST.PRJ_PROJECT_RID = P.PRJ_PROJECT_RID 
LEFT JOIN 
    SEC_USER AS SU ON SU.USER_RID = ST.USER_RID 
LEFT JOIN 
    GOV.REF_PROJECT_TYPE AS R ON P.PROJECT_TYPE_RID = R.PROJECT_TYPE_RID 
WHERE 
    ST.WORK_DATE BETWEEN CAST(@01_STARTDATE AS DATE) AND CAST(@02_ENDDATE AS DATE) 
    AND ST.USER_RID = @STAFF   
    AND R.PROJECT_TYPE_RID = 3 
GROUP BY 
    f.FACILITY_NAME, P.PRJ_PROJECT_NAME, SU.FIRST_NAME, 
    st.work_date, SU.LAST_NAME, R.PROJECT_TYPE_NAME, 
    st.work_hour 

UNION ALL 

SELECT 
    @01_STARTDATE + ' - ' + @02_ENDDATE AS [Date Range], 
    SU.FIRST_NAME + ' ' + SU.LAST_NAME AS Staff, 
    f.FACILITY_NAME AS Site_Name, 
    P.PRJ_PROJECT_NAME AS Project_Name, 
    '' AS Project_Type_Brownfield, 
    R.PROJECT_TYPE_NAME AS Project_Type_VRP, 
    st.work_hour, st.work_date 
FROM 
    FAC_FACILITY AS f 
INNER JOIN 
    GOV.PRJ_PROJECT AS P ON f.FACILITY_RID = p.FACILITY_RID 
INNER JOIN 
    GOV.SYS_TIME_LOG AS ST ON ST.PRJ_PROJECT_RID = P.PRJ_PROJECT_RID 
LEFT JOIN 
    SEC_USER AS SU ON SU.USER_RID = ST.USER_RID 
LEFT JOIN 
    GOV.REF_PROJECT_TYPE AS R ON P.PROJECT_TYPE_RID = R.PROJECT_TYPE_RID 
WHERE 
    ST.WORK_DATE BETWEEN CAST(@01_STARTDATE AS DATE) AND CAST(@02_ENDDATE AS DATE) 
    AND ST.USER_RID = @STAFF   
    AND R.PROJECT_TYPE_RID = 2 
GROUP BY 
    f.FACILITY_NAME, P.PRJ_PROJECT_NAME, SU.FIRST_NAME, 
    st.work_date, SU.LAST_NAME, R.PROJECT_TYPE_NAME, 
    st.work_hour 

UNION ALL 

SELECT 
    @01_STARTDATE + ' - ' + @02_ENDDATE AS [Date Range], 
    SU.FIRST_NAME + ' ' + SU.LAST_NAME AS Staff, 
    g.grant_name AS Site_Name, 
    '' AS project_name, 
    '' AS Project_Type_Brownfield, 
    '' AS Project_Type_VRP, 
    st.work_hour, st.work_date 
FROM 
    (SELECT 
     SUM(work_hour) AS work_hour, user_rid, 
     grant_rid, work_date 
    FROM 
     GOV.SYS_TIME_LOG 
    WHERE 
     WORK_DATE BETWEEN CAST(@01_STARTDATE AS DATE) AND CAST(@02_ENDDATE AS DATE) 
     AND USER_RID = @STAFF   
     AND grant_rid = 1 
    GROUP BY 
     grant_rid, user_rid, work_date) AS ST 
LEFT JOIN 
    SEC_USER AS SU ON SU.USER_RID = ST.USER_RID 
LEFT JOIN 
    SYS_GRANT AS G ON st.grant_rid = g.grant_rid 
WHERE 
    ST.WORK_DATE BETWEEN CAST(@01_STARTDATE AS DATE) AND CAST(@02_ENDDATE AS DATE) 
    AND ST.USER_RID = @STAFF   
    AND st.grant_rid = 1 
GROUP BY 
    SU.FIRST_NAME, st.work_date, SU.LAST_NAME, 
    G.Grant_name, st.work_hour; 
+1

可能重复[SQL Server数据透视表与多个日期列](https://stackoverflow.com/questions/31300884/sql-server-pivot-table-with-multiple-column-with-dates) – JNevill

+0

如果您正在使用支持PIVOT的RDBMS,然后查看有关该命令的供应商文档。既然你标记TSQL,那么我会建议查看第三方报告工具。这种汇总不适合标准的SQL,可能会出现笨拙和容易出错的情况。 –

+0

为什么你的日期变量varchar?列中的数据类型是什么?动态的PIVOT或动态交叉标签可能是您在这里需要的。不太确定你为什么在这里使用UNION ALL。你可以用一个查询来做到这一点。 –

回答

0

有可用的如何“支点”输出例如您的图像看起来像第二个例子不胜枚举。此外,因为您通过参数更改日期范围,您将需要采用“动态sql”生成“动态列名称”。

请注意,您不需要运行3个单独的查询来收集所需的信息,但是应该等待查询的最后一刻抑制值的输出。理想情况下,您不会使用SQL来完成此操作,但会在“表示层”中执行此操作(此查询看起来像是为报表设计的,而大多数报表产品都支持数据的条件输出)。

它只是你的查询了很多,使枢轴更容易实现,如果包括PROJECT_TYPE_RID到两个by子句可以使用这样的CASE表达式控制输出的选择和组:

case when R.PROJECT_TYPE_RID = 1 then '' else Project_Name end AS Project_Name, 
    case when R.PROJECT_TYPE_RID = 3 then R.PROJECT_TYPE_NAME else '' end AS Project_Type_Brownfield, 
    case when R.PROJECT_TYPE_RID = 2 then R.PROJECT_TYPE_NAME else '' end AS Project_Type_VRP, 

但要注意,因为你想使用PIVOT,你将无法做到这一点,像这样抑制值,直到执行完枢轴后。