将查询合并到PIVOT IN列表中的最佳方法?

时间:2018-10-31 20:20:24

标签: sql-server tsql pivot

所以我想拿出一份工资单工作表,这就是我得到的:

SELECT * FROM
    (
    SELECT
        CAST(ad.EmplName AS NVARCHAR(MAX)) AS [EmplName],
        CONVERT(VARCHAR(30), CAST(ad.TicketDate AS DATE), 1) AS [TicketDate],
        ROUND(ad.TotActTime, 2) AS [TotalHrs]
    FROM AttendDet ad
    WHERE ad.EmplCode IS NOT NULL
        AND ad.AttendCode <> '9999'
        AND CONVERT(DATE, ad.TicketDate) BETWEEN '20181022' AND '20181027'
    ) AS BaseData
PIVOT
    (
    SUM(BaseData.TotalHrs)
    FOR BaseData.TicketDate
        IN
        (
        [10/22/18],[10/23/18],[10/24/18],[10/25/18],[10/26/18],[10/27/18], [10/28/18]
        )
    ) AS PivotTable

现在该查询可以正常工作,结果如下:

enter image description here

问题是必须在PIVOT中的IN中键入日期。用查询列表自动执行此操作的最佳方法是什么?

如果我有日期列表,并且说我一直想看看前一周,那么下面的代码可以生成该日期:

SELECT
    CONVERT(VARCHAR(30), CAST(DATEADD(dd,((DATEDIFF(dd,'17530101',GETDATE())/7)*7)-7,'17530101') AS DATE), 1)
UNION
SELECT
    CONVERT(VARCHAR(30), CAST(DATEADD(dd,((DATEDIFF(dd,'17530101',GETDATE())/7)*7)-6,'17530101') AS DATE), 1)
UNION
SELECT
    CONVERT(VARCHAR(30), CAST(DATEADD(dd,((DATEDIFF(dd,'17530101',GETDATE())/7)*7)-5,'17530101') AS DATE), 1)
UNION
SELECT
    CONVERT(VARCHAR(30), CAST(DATEADD(dd,((DATEDIFF(dd,'17530101',GETDATE())/7)*7)-4,'17530101') AS DATE), 1)
UNION
SELECT
    CONVERT(VARCHAR(30), CAST(DATEADD(dd,((DATEDIFF(dd,'17530101',GETDATE())/7)*7)-3,'17530101') AS DATE), 1)
UNION
SELECT
    CONVERT(VARCHAR(30), CAST(DATEADD(dd,((DATEDIFF(dd,'17530101',GETDATE())/7)*7)-2,'17530101') AS DATE), 1)
UNION
SELECT
    CONVERT(VARCHAR(30), CAST(DATEADD(dd,((DATEDIFF(dd,'17530101',GETDATE())/7)*7)-1,'17530101') AS DATE), 1)

问题是,我不知道如何将其合并到我的IN中。我查找了一些有关通过动态SQL进行操作的问题,但是老实说,我什至不知道那是什么,而且我很难将这些示例应用于我的案例。还有另一种方法吗?感谢您的任何帮助,

1 个答案:

答案 0 :(得分:2)

这些天我一直在做一些相关的事情。您可以试试这个;查看并更新它以查看您的数据。为了进一步解释,请您查看评论中附带的链接。

Declare @start_date datetime 
Declare @end_date datetime 
Declare @attendance_code int

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(BASEData.TicketDate) 
FROM (SELECT
        CAST(ad.EmplName AS NVARCHAR(MAX)) AS [EmplName],
        CONVERT(VARCHAR(30), CAST(ad.TicketDate AS DATE), 1) AS [TicketDate],
        ROUND(ad.TotActTime, 2) AS [TotalHrs]
    FROM AttendDet ad 
    GROUP BY p.BASEData.TicketDate) AS x; 
SET @sql = N'

SELECT ' + STUFF(@columns,1,2,'') + ' 
    (
    SELECT
        CAST(ad.EmplName AS NVARCHAR(MAX)) AS [EmplName],
        CONVERT(VARCHAR(30), CAST(ad.TicketDate AS DATE), 1) AS [TicketDate],
        ROUND(ad.TotActTime, 2) AS [TotalHrs]
    FROM AttendDet ad
    WHERE ad.EmplCode IS NOT NULL
        AND ad.AttendCode <> '''@attendance_code'''
        AND CONVERT(DATE, ad.TicketDate) BETWEEN + '''CONVERT(VARCHAR, @start_date)''' AND + '''CONVERT(VARCHAR,@end_date)'''  
    ) AS BaseData
PIVOT
    (
    SUM(BaseData.TotalHrs)
    FOR BaseData.TicketDate
        IN
        (' STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '') 
    ) AS PivotTable;'; 
PRINT @sql; 
EXEC sp_executesql @sql;