我有员工月度出勤表如下。
EmpID EmpName Month Year Day1 Day2 Day3 Day4 ..... Day31
1 ABC Dec 2014 P A WOF PL P
在上表P - 现在,A - 缺席,WOF - 每周OFF,PL - 带薪休假
现在我有以下查询显示特定月份的所有日期,如下所示
declare @StartDate DATE
declare @EndDate DATE
set @StartDate = '20141201'
set @EndDate = '20141231';
WITH DateRange AS
(
SELECT
@StartDate Date1
UNION ALL
SELECT
DATEADD(day, 1, T0.Date1) Date
FROM
DateRange T0
WHERE
T0.Date1 < @EndDate
)
现在我希望得到以下格式的结果
EmpId EmpName Date Status
1 ABC 2014-12-01 P
1 ABC 2014-12-02 A
1 ABC 2014-12-03 WOF
1 ABC 2014-12-04 PL
.
.
.
.
.
.
1 ABC 2014-12-31 P
请回复。谢谢。
答案 0 :(得分:2)
您可以尝试使用这部分代码来实现它:
-- Create demo data
CREATE TABLE #temp(
empId int, EmpName nvarchar(50), month char(3), year int,
day1 varchar(5),day2 varchar(5),day3 varchar(5),day4 varchar(5),day5 varchar(5),day6 varchar(5),day7 varchar(5),
day8 varchar(5),day9 varchar(5),day10 varchar(5),day11 varchar(5),day12 varchar(5),day13 varchar(5),day14 varchar(5),
day15 varchar(5),day16 varchar(5),day17 varchar(5),day18 varchar(5),day19 varchar(5),day20 varchar(5),day21 varchar(5),
day22 varchar(5),day23 varchar(5),day24 varchar(5),day25 varchar(5),day26 varchar(5),day27 varchar(5),day28 varchar(5),
day29 varchar(5),day30 varchar(5),day31 varchar(5)
)
INSERT INTO #temp(empId, EmpName, month, year,
day1 ,day2 ,day3 ,day4 ,day5 ,day6 ,day7 ,
day8 ,day9 ,day10 ,day11 ,day12 ,day13 ,day14 ,
day15 ,day16 ,day17 ,day18 ,day19 ,day20 ,day21 ,
day22 ,day23 ,day24 ,day25 ,day26 ,day27 ,day28 ,
day29 ,day30 ,day31)
VALUES(1,N'Employee1',N'Dec',2014,
N'A',N'B',N'C',N'D',N'E',N'F',N'G',
N'A',N'B',N'C',N'D',N'E',N'F',N'G',
N'A',N'B',N'C',N'D',N'E',N'F',N'G',
N'A',N'B',N'C',N'D',N'E',N'F',N'G',
N'X',N'Y',N'Z')
-- Your Part
SELECT unpvt.empId, unpvt.EmpName,
-- do the day trick
CONVERT(date,
CONVERT(nvarchar(max),unpvt.year)+N'-'
+CONVERT(nvarchar(max),unpvt.month)+N'-'
+REPLACE(unpvt.dayCol,N'Day',N'')
,106) as [Date],
value as [Status]
FROM #temp
UNPIVOT(
value
FOR dayCol IN([day1],[day2],[day3],[day4],[day5],[day6],[day7],
[day8],[day9],[day10],[day11],[day12],[day13],[day14],
[day15],[day16],[day17],[day18],[day19],[day20],[day21],
[day22],[day23],[day24],[day25],[day26],[day27],[day28],
[day29],[day30],[day31])
) as unpvt
-- Cleanup
DROP TABLE #temp
我正在使用UNPIVOT
将列转换为行。之后,我替换列名以获取日期编号,并从中生成datetime
列。
但除此之外,这将解决您的问题,桌面设计非常糟糕。无论如何,我确信你没有设计这个,你只需要处理它。 : - )
答案 1 :(得分:1)
您可以像这样使用UNPIVOT
。
<强>查询强>
SELECT EmpID,EmpName,
CONVERT(DATE,REPLACE(Col,'Day','') + ' ' + [Month] + ' ' + CONVERT(VARCHAR(20),[Year]),106) AttDate,
Val
FROM EmpATT
UNPIVOT(Val FOR Col IN([Day1], [Day2], [Day3], [Day4], [Day31])) as UPVT
<强>输出强>
| EmpID | EmpName | AttDate | Val |
|-------|---------|------------|-----|
| 1 | ABC | 2014-12-01 | P |
| 1 | ABC | 2014-12-02 | A |
| 1 | ABC | 2014-12-03 | WOF |
| 1 | ABC | 2014-12-04 | PL |
| 1 | ABC | 2014-12-31 | P |
答案 2 :(得分:0)
尝试这个,以便动态地将列设置为几天。
declare @columnName nvarchar(max) = ''
declare @ex nvarchar(max) = ''
select @columnName += quotename(COLUMN_NAME) + ',' from (select * from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'DateRange' and COLUMN_NAME like 'day%')
set @columnName = LEFT(@columnname,len(@columnname) - 1)
set @ex = '
select .... from DateRange
pivot ....
for ....
in (' + @columnName+ ')) as pivotT'
exec sp_executesql @ex