从动态表中选择时更改列名
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 函数。
通常,当我动态获取列列表时,我的首选是使用STUFF
和FOR 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
【讨论】:
以上是关于从动态表中选择时更改列名的主要内容,如果未能解决你的问题,请参考以下文章