Лучший способ включить запрос в список PIVOT IN? - PullRequest
0 голосов
/ 31 октября 2018

, так что я пытаюсь придумать лист с зарплатой, и вот что я получил:

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

Проблема в том, что нужно вводить даты внутри IN в PIVOT. Каков наилучший способ сделать это автоматически со списком из запроса?

Если у меня есть список дат и, скажем, я всегда хотел посмотреть на предыдущую неделю, то приведенный ниже код может сгенерировать это:

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 голосов
/ 31 октября 2018

Я работал над чем-то связанным в эти дни. Вы можете попробовать это; просмотрите и обновите его, изучив ваши данные. Для дальнейшего объяснения, вы можете просмотреть ссылку, прикрепленную к комментарию.

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; 
...