SQL 多值动态数据透视

问题描述 投票:0回答:1

下面是我当前的代码。

我想在这段代码中做什么:

#BySite 表有一个记录列表,其中 PlayMonth 列之前列出的所有列都是自 10/1/2021 以来每个月月底的快照。 PlayMonth 到 Actual 的列是自 2021 年 10 月 1 日以来每个月的值。例如,如果玩家有 2024 年 1 月至 2024 年 3 月的记录,则将有 2024 年 1 月 3 日的记录,其中包含 1 月、2 月和 3 月的游戏数据。2024 年 2 月 2 日的记录将包含 2 月和 2 月的游戏数据。三月。目前,三月只有 3 月的播放数据,其中有 1 条记录。当新的一个月过去时,每个月都会获得 4 月的新记录。而不是添加新行。我想将行旋转为一组动态列,以便该玩家将有 3 行第一行表示一月、二月和三月。这些列将展开并成为 Jan_Theo、Jan_Acutal、Feb_Theo、Feb_Actual、Mar_Theo、Mar_Actual。当 Apr 完成时,Apr_Theo,Apr_Actual。对于该行月份之前的月份,这些值将为空。另外,我只用枢轴测试了两个值,但我将添加更多值。 ClubLevel、Property、Trips、Theo、Actual、FP 是需要旋转的列的完整列表。

我作为一个整体正在尝试做的事情,以防有更好的方法来解决这个问题:

我们的目标是能够在报告中比较任何玩家在一个月与另一个月的行为,最终用户可以选择任意两个月并进行比较。

DECLARE @cols AS NVARCHAR(MAX)
DECLARE @Query AS NVARCHAR(MAX)

SELECT @cols = STUFF((
    SELECT ',' + QUOTENAME(PlayMonth)
    FROM (
        SELECT DISTINCT CAST(BS.Playyear AS VARCHAR(20)) + '|' + CAST(BS.PlayMonth AS VARCHAR(20)) AS PlayMonth
        FROM #BySite AS BS
    ) AS PivotColumns
    FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SET @Query = '
SELECT *
FROM (
    SELECT BS.EndingClubLevel
        , BS.PropertyName
        , BS.Year
        , BS.Month
        , BS.Universal_ID
        , BS.Old_Trips
        , BS.Old_Theo
        , BS.Old_Actual
        , BS.Old_FP
        , CAST(BS.Playyear AS VARCHAR(20)) + ''|'' + CAST(BS.PlayMonth AS VARCHAR(20)) AS PlayMonth
        , BS.CurrentClubLevel as ClubLevel
        , BS.PlayProperty as Property
        , BS.Trips
        , BS.theo
        , BS.Actual
        ,BS.FP
    FROM #BySite AS BS
) AS Src

PIVOT (
    AVG(theo) FOR PlayMonth IN (' + @cols + ')
) AS TheoPivot
PIVOT (
    AVG(Actual) FOR PlayMonth IN (' + @cols + ')
) AS ActualPivot';

EXEC sp_executesql @Query;

编辑:请求了示例数据以及所需的输出,这是有道理的,所以下面是这样的。我用颜色对其进行了编码,以便我可以尝试帮助解释。有两名球员的记录,一名是浅橙色的,一名是灰色的。绿色标头是静态标头,是给定月份的快照。紫色标题包含每个月的值,是我想要动态透视的值。一旦工作,这将使其结果部分非常宽,并且每月总是以 6 列的速度增长。

编辑2:

如果我运行代码时将 ClubLevel、Property、Trips、Actual 和 FP 全部注释掉,并将第二个主元注释掉,那么它会按预期/期望工作。当我添加回实际的列和实际的枢轴时,我收到以下错误。每个月年组合都会继续。

我正在尝试按照我在该网站上看到的最小、最大示例的方式创建一些内容SQL Pivot

我知道在这个例子中他们只是做了一个具有多个值的数据透视,但我也没有让它运行没有错误。

Msg 207, Level 16, State 1, Line 129
Invalid column name 'PlayMonth'.
Msg 265, Level 16, State 1, Line 129
The column name "2021|11" specified in the PIVOT operator conflicts with the existing column name in the PIVOT argument.
Msg 265, Level 16, State 1, Line 129
The column name "2021|12" specified in the PIVOT operator conflicts with the existing column name in the PIVOT argument.
sql-server pivot sql-server-2016 dynamic-sql
1个回答
0
投票

我找到了答案。我必须将每个列分解为自己的变量,并在数据透视中使用它,以便它们都具有唯一的列名称。

DECLARE @Theo AS NVARCHAR(MAX)
DECLARE @Actual AS NVARCHAR(MAX)
DECLARE @Query AS NVARCHAR(MAX)

SELECT @Theo = STUFF((
    SELECT ',' + QUOTENAME(TheoBreakout)
    FROM (
        SELECT DISTINCT CAST(BS.Playyear AS VARCHAR(20)) + '|' + CAST(BS.PlayMonth AS VARCHAR(20))+ '|Theo' AS TheoBreakout
        FROM #BySite AS BS
    ) AS PivotColumns
    FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SELECT @Actual = STUFF((
    SELECT ',' + QUOTENAME(ActualBreakout)
    FROM (
        SELECT DISTINCT CAST(BS.Playyear AS VARCHAR(20)) + '|' + CAST(BS.PlayMonth AS VARCHAR(20)) + '|Actual' AS ActualBreakout
        FROM #BySite AS BS
    ) AS PivotColumns
    FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SET @Query = '
SELECT *
FROM (
    SELECT BS.EndingClubLevel
        , BS.PropertyName
        , BS.Year
        , BS.Month
        , BS.Universal_ID
        , BS.Old_Trips
        , BS.Old_Theo
        , BS.Old_Actual
        , BS.Old_FP
        , CAST(BS.Playyear AS VARCHAR(20)) + ''|'' + CAST(BS.PlayMonth AS VARCHAR(20))+ ''|Theo'' AS TheoBreakout
        , CAST(BS.Playyear AS VARCHAR(20)) + ''|'' + CAST(BS.PlayMonth AS VARCHAR(20)) + ''|Actual'' AS ActualBreakout
        --, BS.CurrentClubLevel
        
      --  , BS.PlayProperty
        , BS.theo
       , BS.Actual
    FROM #BySite AS BS
) AS Src

PIVOT (
    AVG(theo) FOR TheoBreakout IN (' + @Theo + ')
) AS TheoPivot
PIVOT (
    AVG(Actual) FOR ActualBreakout IN (' + @Actual + ')
) AS ActualPivot'

EXEC sp_executesql @Query;
© www.soinside.com 2019 - 2024. All rights reserved.