SQL查询 - 行到列但没有透视

时间:2015-12-28 20:20:35

标签: sql sql-server pivot

我需要一种有效的方法将行中返回的数据转换为我正在处理的足球数据库的列。

2张桌子,一个拿着固定装置,一个拿着预测。

Fixtures

enter image description here

Predictions

enter image description here

我希望这两个表中的数据返回如下(不能发布另一个链接,但是这个查询会给你一个想法):

SELECT  1 as UserID, 
    2 as [Stoke vs Man United], 
    1 as [Bournemouth vs Crystal Palace], 
    2 as [Swansea vs West Brom],
    1 as [Chelsea vs Watford],
    3 as [Liverpool vs Leicester],
    1 as [Tottenham vs Norwich],
    2 as [Aston Villa vs West Ham]

问题是,每周,所选择的团队都会发生变化,因此我无法获得透视查询。有任何想法吗?

2 个答案:

答案 0 :(得分:0)

要完成这项工作需要了解的两件事。

  1. Dynamic Pivot
  2. sp_executesql
  3. 实施例

    -- Param Definitions
    DECLARE @Sql NVARCHAR(MAX),
            @Columns NVARCHAR(MAX),
            @WeekNo INT = 6,
            @UserID INT = 1,
            @Params NVARCHAR(MAX) = N'@Week INT, @User INT'
    
    -- Dynamic Column Names
    SELECT  @Columns = COALESCE(@Columns + ',','') + QUOTENAME(HomeTeamName + ' vs ' + AwayTeamName)
    FROM    usr_SS_Fixtures
    WHERE   WeekNo = @WeekNo
    
    -- Dynamic SQL
    SET @Sql = N'
    SELECT *
    FROM
    (
        SELECT 
            pred.UserId,
            pred.ResultCode,
            CONCAT(HomeTeamName,'' vs '', AwayTeamName) AS Teams
        FROM
            usr_SS_Fixtures fix
            JOIN usr_SS_Predictions pred ON fix.EventID = pred.EventID AND fix.WeekNo = pred.WeekNo
        WHERE 
            fix.WeekNo = @Week
            AND pred.UserID = @User
    ) t
    PIVOT 
    (
        MAX(ResultCode)
        FOR Teams IN (' + @Columns + ')
    ) p
    '
    
    -- Executes the dynamic SQL
    EXECUTE sp_executesql @Sql, @Params, @Week = @WeekNo, @User = @UserID
    

    DEMO

答案 1 :(得分:0)

正常的动态数据透视问题有一个有趣的变化,因为已知的最大游戏数量,这使得一个可能的解决方案更简单一点。试试下面的SQL;它会创建一个第一行,其中包含所需的列标题,这可能足以用于简单的显示目的。

declare @weekNo as int = 6
       ,@UserID as int = 1;   
with
fixture(UserID, EventID, [Value], GameNo) as (
    select -1, EventID, AwayTeamName + ' at ' + HomeTeamName
        , row_number() over (partition by WeekNo order by EventID)
    from usr_SS_Fixtures
),
prediction(UserID, EventID, [Value], GameNo)  as (
    select UserID, EventID, ResultCode
        , row_number() over (partition by WeekNo order by EventID)
    from usr_SS_Predictions
),
data as (
    select
         WeekNo, UserID
        ,[1],[2],[3],[4],[5],[6],[7]
    from (
        select WeekNo, UserID, EventID, [Value] from fixture
        union all
        select WeekNo, UserID, EventID, [Value] from prediction
    ) T
    pivot (
        max([Value]) for GameNo in ([1],[2],[3],[4],[5],[6],[7])
    ) pvt
)
select
    UserID,[1],[2],[3],[4],[5],[6],[7]
from data
where WeekNo = @WeekNo
order by
    UserID