从动态表中选择时更改列名称

时间:2013-05-03 13:22:59

标签: sql sql-server tsql pivot

您好我有一个关注查询,它将使用PIVOT函数

生成关注度报告

以下是程序:

declare  @in_date DATETIME       

/*Select all the stagign entries related to promotion id and investment type id */    
  /* also only those staging daat related interface status tracking*/

  -- Getting all distinct dates into a temporary table #Dates
    SELECT a.date as full_date_of_attendence INTO #Dates
    FROM dbo.getFullmonth(@in_date) a
    ORDER BY a.date



    -- The number of days will be dynamic. So building
    -- a comma seperated value string from the dates in #Dates
    SELECT  @cols = COALESCE(@cols + ',[' + CONVERT(varchar, full_date_of_attendence, 106)
                                    + ']','[' + CONVERT(varchar, full_date_of_attendence, 106) + ']')
    FROM    #Dates
    ORDER BY full_date_of_attendence


    --select @cols

    ---- Building the query with dynamic dates

SET @qry =
    'SELECT * FROM
    (SELECT admission_id, attendence_status , date_of_attendence
    FROM dbo.tblattendence)emp
    PIVOT (MAX(attendence_status) FOR date_of_attendence IN (' + @cols + ')) AS stat'    



    -- Executing the query
    EXEC(@qry)

    -- Dropping temporary tables
    DROP TABLE #Dates

这是上述查询::

的输出
admission_id    01 May 2013 02 May 2013 03 May 2013
2                NULL               1               0
3                NULL               1               1
4                NULL               0               0
5                NULL               0               1

在这里,我想将列的名称更改为01,02,03...... 我希望值1为“P”,0为“A”

任何人都可以帮助我实现这个目标吗?

2 个答案:

答案 0 :(得分:0)

我建议您对代码进行以下更改。如果你想要一个日期列表(1,2,3等),那么你可以使用DAY函数。

通常,当我动态获取列列表时,我的偏好是使用STUFFFOR XML PATH,我会将该代码更改为以下内容:

select @colsPiv = STUFF((SELECT ',' + QUOTENAME(cast(day(full_date_of_attendence) as varchar(2))) 
                from #Dates
                GROUP BY full_date_of_attendence
                ORDER BY full_date_of_attendence
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')

然后,如果您要将0替换为A,将1替换为P,则需要创建查询以获取列列表替换值:

select @colsSel = STUFF((SELECT ', case when ' + QUOTENAME(cast(day(full_date_of_attendence) as varchar(2)))+'= 1 then ''P'' else ''A'' end as '+QUOTENAME(cast(day(full_date_of_attendence) as varchar(2)))
                      from #Dates
                      GROUP BY full_date_of_attendence
                      ORDER BY full_date_of_attendence
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
                ,1,1,'')

基本上,这是创建一个类似于此的选择列表:

select case when [1] = 1 then 'P' else 'A' end as [1], ...

然后您的最终查询将是:

SET @qry =
'SELECT admission_id, '+@colsSel +' 
 FROM
 (
    SELECT admission_id, 
      attendence_status , 
      day(date_of_attendence) date_of_attendence
    FROM dbo.tblattendence
 )emp
 PIVOT 
 (
    MAX(attendence_status) 
    FOR date_of_attendence IN (' + @colsPiv + ')
 ) AS stat'   

请参阅SQL Fiddle with Demo

答案 1 :(得分:0)

让我们改变你想要的两件事,即

  1. CONVERT(CHAR(2), full_date_of_attendence, 106) - 使用CHAR(2)代替varchar
  2. SELECT中的
  3. CASE attendence_status when 1 then 'P' else 'A' END
  4. 具有最小更改的代码。希望这有助于您了解如何在将来对其他代码进行类似的更改。

    declare @in_date DATETIME
    
    /*Select all the stagign entries related to promotion id and investment type id */    
    /* also only those staging daat related interface status tracking*/
    
    -- Getting all distinct dates into a temporary table #Dates
    SELECT a.date as full_date_of_attendence INTO #Dates
    FROM dbo.getFullmonth(@in_date) a
    ORDER BY a.date
    
    
    
    -- The number of days will be dynamic. So building
    -- a comma seperated value string from the dates in #Dates
    SELECT  @cols = COALESCE(@cols + ',', '') + [' +
            CONVERT(CHAR(2), full_date_of_attendence, 106) + ']'
    FROM    #Dates
    ORDER BY full_date_of_attendence
    
    
    --select @cols
    
    ---- Building the query with dynamic dates
    
    SET @qry =
    'SELECT * FROM
    (SELECT admission_id, CASE attendence_status when 1 then 'P' else 'A' END, date_of_attendence
    FROM dbo.tblattendence)emp
    PIVOT (MAX(attendence_status) FOR date_of_attendence IN (' + @cols + ')) AS stat'    
    
    
    
    -- Executing the query
    EXEC(@qry)
    
    -- Dropping temporary tables
    DROP TABLE #Dates