【问题标题】:Getting PIVOT using GroupBy使用 GroupBy 获取 PIVOT
【发布时间】:2013-09-19 19:07:25
【问题描述】:

我有这张桌子:

Person      Job     Day  EndDay
1           101     1    12
1           102     2    11
1           103     3    11
3           101     1    11
3           102     2    11 
3           JobOff  3    11
2           101     1    11
2           102     2    11
2           103     3    11
2           JobOff  4    11
...

PS:我的日子最多是'N',我不知道。所以,静态 SQL 在这里是行不通的。

我需要将其更改为这种形式:

Day (Columns)
Person  (Rows)
Person  1    2    3       4
1       101  102  103     N/A
2       101  102  103     JobOff
3       101  102  JobOff  N/A

任何帮助将不胜感激。我是 SQL 新手。

感谢 Roman,我有这个 S.Procedure:

CREATE PROCEDURE [dbo].[MyStoredProcedure] AS
BEGIN

declare @stmt nvarchar(max)

select @stmt =
    isnull(@stmt + ', ', '') + 
    'isnull(max(case when [Day] = ' + cast([Day_I] as nvarchar(max)) + 
    ' then Job end), ''N/A'') as [' + cast([Day_I] as nvarchar(max)) + ']'
from (select distinct [Day_I] from dbo.Solution) as t
order by [Day_I]

select @stmt = '
select
    Person_I, ' + @stmt +'
from dbo.Solution_Format
group by Person_I'

END

但是当我像这样执行这个存储过程时:

exec MyStoredProcedure

它显示没有结果。没有错误!

【问题讨论】:

    标签: sql sql-server sql-server-2008 pivot pivot-table


    【解决方案1】:
    select
        Person,
        isnull(max(case when [Day] = 1 then Job end), 'N/A') as [1],
        isnull(max(case when [Day] = 2 then Job end), 'N/A') as [2],
        isnull(max(case when [Day] = 3 then Job end), 'N/A') as [3],
        isnull(max(case when [Day] = 4 then Job end), 'N/A') as [4]
    from Table1
    group by Person
    

    sql fiddle demo

    如果您需要任意数量的列,也可以使用动态 SQL 执行此操作:

    create procedure [dbo].[MyStoredProcedure]
    as
    begin   
        declare @stmt nvarchar(max)
    
        select @stmt =
            isnull(@stmt + ', ', '') + 
            'isnull(max(case when [Day] = ' + cast([Day] as nvarchar(max)) + 
            ' then Job end), ''N/A'') as [' + cast([Day] as nvarchar(max)) + ']'
        from (select distinct [Day] from Table1) as t
        order by [Day]
    
        select @stmt = '
        select
            Person, ' + @stmt +'
        from Table1
        group by Person'
    
        exec sp_executesql
            @stmt = @stmt
    end
    

    sql fiddle demo

    【讨论】:

    • 谢谢!但是,我的天数(列)最多为 63 天。您的动态解决方案是否有效?
    • @RG-3 你忘了执行语句 - exec sp_executesql @stmt = @stmt
    • 但是,当我通过 C# 调用这个 SProc 时,我不想输入任何内容作为参数:\
    • 您不必输入参数。只需创建不带参数的过程并将整个语句写入其中
    • @RomanPekar:请查看我在问题中的编辑。你会明白要点的。
    【解决方案2】:

    一种方法是使用多个自连接

    Select
      t1.Person,
      COALESCE(t1.Job, 'N/A') [1],
      COALESCE(t2.Job, 'N/A' )[2],
      COALESCE(t3.Job, 'N/A') [3], 
      COALESCE(t4.Job, 'N/A') [4]
    FROM 
      table1 t1
      LEFT JOIN table1  t2
      ON t1.Person =  t2.Person
        and t2.Day = 2
      LEFT JOIN table1  t3
       ON t1.Person =  t3.Person
         and t3.Day = 3
      LEFT JOIN table1  t4
        ON t1.Person =  t4.Person
         and t4.Day = 4
    WHERE
       t1.Day = 1
    ORDER BY 
      t1.Person
    

    DEMO

    另一种方法是使用 MAX(CASE 但是我不喜欢使用这样的聚合。

    Select
      t1.Person,
      COALESCE(MAX(CASE WHEN t1.Day = 1 then t1.Job END), 'N/A') [1],
      COALESCE(MAX(CASE WHEN t1.Day = 2 then t1.Job END), 'N/A') [2],
      COALESCE(MAX(CASE WHEN t1.Day = 3 then t1.Job END), 'N/A') [3],
      COALESCE(MAX(CASE WHEN t1.Day = 4 then t1.Job END), 'N/A') [4]
    
    FROM 
      table1 t1
    GROUP BY
      t1.Person
    

    DEMO

    最后还有一个我不太喜欢的 pivot 子句,因为这里有 MAX

    SELECT person, 
           COALESCE([1], 'N/A') [1], 
           COALESCE([2], 'N/A') [2], 
           COALESCE([3], 'N/A') [3], 
           COALESCE([4], 'N/A') [4] 
    FROM   (SELECT t1.person, 
                   t1.day, 
                   t1.job 
            FROM   table1 t1) p 
           PIVOT (Max (job) 
                 FOR day IN ( [1], 
                              [2], 
                              [3], 
                              [4]) ) AS pvt 
    

    DEMO

    【讨论】:

    • 我的天数(列)高达 63 天或更多……如果我这样继续下去,那将是很多行代码。
    • @RG-3 好吧,您可以很容易地生成 SQL 语句。是否在运行时生成它应该取决于您的要求。
    猜你喜欢
    • 2013-08-26
    • 2020-09-08
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    相关资源
    最近更新 更多