2015-07-21 2 views
1

У меня есть таблица ежемесячных посетителей Employee следующим образом.SQL Server выбирает columnn как строки динамически в результирующем наборе

EmpID EmpName Month Year  Day1 Day2 Day3 Day4 ..... Day31 

1  ABC  Dec 2014  P  A  WOF  PL   P 

В приведенной выше таблице P - присутствует, - отсутствует, 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 

Пожалуйста reply.Thanks.

ответ

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 | 

SQL Fiddle

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.

Но помимо этого это решит вашу проблему, дизайн стола действительно ужасен. Во всяком случае, я уверен, что вы не разработали это, и вам просто нужно справиться с этим. :-)

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 
Смежные вопросы