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

Posted

技术标签:

【中文标题】从动态表中选择时更改列名【英文标题】:change the column name while selecting from dyanamic table 【发布时间】:2013-05-03 13:22:59 【问题描述】:

您好,我有考勤查询,它将使用 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'

谁能帮我实现这个目标??

【问题讨论】:

使用 Select admission_id 作为 AdmsnId FROM dbo.tblattendence 【参考方案1】:

我建议对您的代码进行以下更改。如果您想要日期列表(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,'')

然后,如果您想用A 替换0 和用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

【讨论】:

【参考方案2】:

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

    CONVERT(CHAR(2), full_date_of_attendence, 106) -- 使用 CHAR(2) 代替 varchar CASE attendence_status when 1 then 'P' else 'A' END 在 SELECT...

更改最少的代码。希望这可以帮助您了解将来如何对其他代码进行类似的更改。

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

【讨论】:

以上是关于从动态表中选择时更改列名的主要内容,如果未能解决你的问题,请参考以下文章

从动态表中选择到 Datatable Oracle

SQL - 如何从多个可能的列名中进行选择?

从连接表列表中选择唯一的列名

mysql选择动态行值作为列名,另一列作为值

有没有办法动态更改 JQwidget 网格列的数据源以及列名

如何让 python 使用 Flask 和 JINJA2 从动态表中检索用户输入的数据