簡體   English   中英

PIVOT 使用 2 個值和一個日期列進行查詢

[英]PIVOT Query With 2 values and a Date Column

我們最近將我們的一些表從 Access 轉換為 SQL 服務器,我想將此 Access Crosstab 查詢重現到 SQL 服務器

TRANSFORM First(IIf([FieldName]="Engagement",IIf([Engagement]=1,"Yes","No"),IIf([Interactive]=1,"Yes",IIf([Interactive]=0,"No","N/A")))) AS TheValue
SELECT tblStudent.Surname, tblStudent.Forename
FROM tblXtabColumns, tblStudent INNER JOIN tblEngagement ON tblStudent.SID = tblEngagement.SID
WHERE (((tblEngagement.Class)=[Class?]))
GROUP BY tblStudent.Surname, tblStudent.Forename
PIVOT [FieldName] & " " & Day([AttendTime]) & " " & MonthName(Month([AttendTime]),True);

表 tblEngagement 在數據庫中看起來像這樣

SID         AttendTime          Engagement  Interactive
12345       01/01/2020 14:00    1           1
56789       01/01/2020 14:00    1           0
12345       07/01/2020 14:00    1           1
56789       07/01/2020 14:00    1           1
12345       14/01/2020 14:00    1           0
56789       14/01/2020 14:00    1           1

我希望 pivot 查詢像這樣生成它

SID   Engagement 1 Jan  Interactive 1 Jan   Engagement 7 Jan    Interactive 7 Jan   Engagement 14 Jan   Interactive 14 Jan
12345 Yes               Yes                 Yes                 Yes                 Yes             No
56789 Yes               No                  Yes                 Yes                 Yes            Yes

我已經設法編寫了一個 SQL 服務器查詢,其中只有 Engagement 列,它是:

DECLARE @Lesson varchar(2000)
    DECLARE @Query varchar(4000)
    SELECT @Lesson = STUFF(( SELECT DISTINCT 
                            '],[' + CONVERT(varchar, AttendTime) 
                            FROM tblEngagement 
                            ORDER BY '],[' + CONVERT(varchar, AttendTime)  
                            FOR XML PATH('')), 1, 2, '') + ']'

    SET @Query =
    'SELECT * 
    FROM 
        ( SELECT SID, AttendTime, Engagement 
            FROM tblEngagement  
        ) ps
    PIVOT
        ( MAX(Engagement)
            FOR AttendTime IN ('+ @Lesson +')
        ) AS pvt1
    '

    EXECUTE (@Query)

這給了我這個

SID Jan 1 2020  Jan 7 2020
12345   1       0
56789   0       1

我嘗試過以下操作

DECLARE @Lesson varchar(2000)
DECLARE @Query varchar(4000)
SELECT @Lesson = STUFF(( SELECT DISTINCT 
                        '],[' + CONVERT(varchar, AttendTime) 
                        FROM tblEngagement 
                        ORDER BY '],[' + CONVERT(varchar, AttendTime)  
                        FOR XML PATH('')), 1, 2, '') + ']'

SET @Query =
'SELECT * 
FROM 
    ( SELECT SID, AttendTime, Engagement, Interactive 
        FROM tblEngagement  
    ) ps
PIVOT
    ( MAX(Engagement)
        FOR AttendTime IN ('+ @Lesson +')
    ) AS pvt1
PIVOT
    ( MAX(Interactive)
        FOR AttendTime IN ('+ @Lesson +')
    ) AS pvt2
'
EXECUTE (@Query)

但這給了我錯誤:

Msg 207, Level 16, State 1, Line 15
Invalid column name 'AttendTime'.
Msg 265, Level 16, State 1, Line 15
The column name "Jan  1 2020  2:00PM" specified in the PIVOT operator conflicts with the existing column name in the PIVOT argument.
Msg 265, Level 16, State 1, Line 15
The column name "Jul 7 2020  2:00PM" specified in the PIVOT operator conflicts with the existing column name in the PIVOT argument.
Msg 8156, Level 16, State 1, Line 16
The column 'Jan  1 2020  2:00PM' was specified multiple times for 'pvt2'

只是指出每周都會添加更多數據,希望這是有道理的。

嘗試這個:

DROP TABLE IF EXISTS #DataSource;

CREATE TABLE #DataSource
(
    [SID] INT
   ,[AttendTime] DATETIME2
   ,[Engagement] TINYINT
   ,[Interactive] TINYINT
);

INSERT INTO #DataSource ([SID], [AttendTime], [Engagement], [Interactive])
VALUES (12345, '2020/01/01 14:00', 1, 1)
      ,(56789, '2020/01/01 14:00', 1, 0)
      ,(12345, '2020/01/07 14:00', 1, 1)
      ,(56789, '2020/01/07 14:00', 1, 1)
      ,(12345, '2020/01/14 14:00', 1, 0)
      ,(56789, '2020/01/14 14:00', 1, 1);


DECLARE @columns NVARCHAR(MAX);

SELECT @columns = STUFF
(
    (
        SELECT ',' + QUOTENAME([RowValue])
        FROM
        (
            SELECT DENSE_RANK() OVER (ORDER BY [AttendTime]) + 0.1
                  ,CONCAT('Engagement ', DAY([AttendTime]), ' ' ,LEFT(DATENAME(MONTH, MONTH([AttendTime])), 3)) 
            FROM #DataSource
            UNION
            SELECT DENSE_RANK() OVER (ORDER BY [AttendTime]) + 0.2
                  ,CONCAT('Interactive ', DAY([AttendTime]), ' ' ,LEFT(DATENAME(MONTH, MONTH([AttendTime])), 3))
            FROM #DataSource
        ) DS ([RowID], [RowValue])
        ORDER BY [RowID]
        FOR XML PATH(''), TYPE
    ).value('.', 'VARCHAR(MAX)')
    ,1
    ,1
    ,''
);

DECLARE @DanymicSQL NVARCHAR(MAX);

SET @DanymicSQL = N'
SELECT [SID], ' + @columns + '
FROM
(
    SELECT [SID]
          ,CONCAT(''Engagement '', DAY([AttendTime]), '' '' ,LEFT(DATENAME(MONTH, MONTH([AttendTime])), 3))
          ,IIF([Engagement] = 1, ''Yes'', ''No'')
    FROM #DataSource
    UNION ALL
    SELECT [SID]
          ,CONCAT(''Interactive '', DAY([AttendTime]), '' '' ,LEFT(DATENAME(MONTH, MONTH([AttendTime])), 3))
          ,IIF([Interactive] = 1, ''Yes'', ''No'')
    FROM #DataSource
) DS ([SID], [column], [value])
PIVOT
(
    MAX([value]) FOR [column] IN (' + @columns + ')
) PVT';

EXEC sp_executesql @DanymicSQL;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM