SQL Pivot - 如何显示具有空值的所有行?

时间:2016-08-26 20:55:51

标签: sql sql-server join pivot row

有没有办法使用Pivot包含空值的行?

理想情况下,我想要像这样的输出

enter image description here

然而,目前Pivot并没有返回空行,我正在获得这样的输出

enter image description here

我正在使用下面的代码获取结果集:

SELECT
    ID,
    Name,
    Design,
    month
FROM (SELECT
    E.EnrollId AS ID,
    E.EmployeeName AS Name,
    D.Designation AS
    Design,
    DATENAME(MONTH, La.Date) AS month,
    DATENAME(DAY, La.Date) AS Day,
    L.LeaveShortName AS Short
FROM Employee E
JOIN LeaveApplicationDates LA
    ON E.EnrollId = LA.EnrollId
JOIN Leave L
    ON L.LeaveId = LA.LeaveId
JOIN Designation D
    ON E.DesignationId = D.DesignationId
WHERE (E.EnrollId = '10277')
AND (La.Date BETWEEN '1/1/2016' AND '8/1/2016')) AS setr
PIVOT
(
MAX(Short)
FOR [Day] IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10],
[11], [12], [13], [14], [15], [16], [17], [18], [19], [20],
[21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31])
) AS pivotTable

I follow this but solution not working

1 个答案:

答案 0 :(得分:1)

您可以使用CTE获取包含月份名称的表格:

;WITH cte AS (
    SELECT  CAST('2016-01-01' as datetime) as d
    UNION ALL
    SELECT  DATEADD(month,1,d)
    FROM cte
    WHERE DATEPART(month,d) < 12
)

SELECT  DATEPART(month,d) as month_num,
        DATENAME(month,d) as month_name
FROM cte

输出:

month_num   month_name
1           January
2           February
3           March
4           April
5           May
6           June
7           July
8           August
9           September
10          October
11          November
12          December

并将其放入您的查询中,例如:

;WITH cte AS (
    SELECT  CAST('2016-01-01' as datetime) as d
    UNION ALL
    SELECT  DATEADD(month,1,d)
    FROM cte
    WHERE DATEPART(month,d) < 12
)

SELECT  ID,
        Name,
        Design,
        [month],
        [1], [2], [3], [4], [5], [6], [7], [8], [9], [10],
[11], [12], [13], [14], [15], [16], [17], [18], [19], [20],
[21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31]
FROM (
    SELECT  E.EnrollId AS ID,
            E.EmployeeName AS Name,
            D.Designation AS
            Design,
            month_num,
            month_name AS [month],
            DATENAME(DAY, La.[Date]) AS [Day],
            L.LeaveShortName AS Short
    FROM Employee E
    CROSS JOIN (
        SELECT  DATEPART(month,d) as month_num,
                DATENAME(month,d) as month_name
        FROM cte
        ) as mt
    LEFT JOIN LeaveApplicationDates LA
        ON E.EnrollId = LA.EnrollId and mt.month_name = DATENAME(MONTH, La.[Date]) and La.[Date] BETWEEN '1/1/2016' AND '8/1/2016'
    LEFT JOIN Leave L
        ON L.LeaveId = LA.LeaveId
    LEFT JOIN Designation D
        ON E.DesignationId = D.DesignationId
) AS setr
PIVOT
(
MAX(Short)
FOR [Day] IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10],
[11], [12], [13], [14], [15], [16], [17], [18], [19], [20],
[21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31])
) AS pivotTable
WHERE ID = '10277'
ORDER BY ID, month_num