0

请解决我的表测试

标识整数
Emp_ID 整数
准时日期时间

从测试中选择 *

Id Emp_ID 准时
1 1 2013-02-11 2:14:25.387  
2 2 2013-02-11 14:14:25.387
1 1 2013-02-11 20:14:25.387
3 3 2013-02-13 10:14:25.387
4 2 2013-02-13 10:14:25.387
5 1 2013-02-13 10:14:25.387
6 1 2013-02-14 11:14:25.387

我的要求这个

用户输入两个日期并记录显示每天计数明智

只记录

日期 1=11/2/2013 日期 2=13/2/2013

Emp_ID 2013 年 11 月 2 日 2013 年 12 月 2 日 2013 年 13 月 2 日
1 2 0 1
2 1 0 1
3 0 0 1

谢谢


谢谢

但是这个 tbl_emp

Emp_ID int Emp_name varchar

| EMP_ID | 2013-02-11 | 2013-02-12 | 2013-02-13 |
-------------------------------------------------
| 1 | 2 | 0 | 1 |
| 2 | 1 | 0 | 1 |
| 3 | 0 | 0 | 1 |
| 4 | 0 | 0 | 0 |

Emp_ID 4 未插入测试表

4

1 回答 1

3

这种类型的数据转换称为PIVOT. 从 SQL Server 2005 开始,有一个函数可以为您执行此操作。

如果您提前知道这些值,则可以对查询进行硬编码,如下所示:

select *
from
(
  select id,
    [Emp_ID], 
    cast([ontime] as date) ontime
  from test
) src
pivot
(
  count(id)
  for ontime in ([2013-02-11], [2013-02-12], [2013-02-13])
) piv

请参阅SQL Fiddle with Demo

如果要转换的列数未知,则需要使用动态 SQL。这可以通过使用WHERE子句进一步过滤以仅查找某些日期:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast([ontime] as date)) 
                    from test
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT emp_id,' + @cols + ' from 
             (
                select Emp_ID pivId,
                  [Emp_ID], 
                  cast([ontime] as date) ontime
                from test
            ) x
            pivot 
            (
                count(pivId)
                for ontime in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle with Demo

如果你想保证你会返回你想要的日期,那么你可以先生成一个日期列表。因此,您的整个动态 SQL 脚本将是:

declare @startdate datetime
declare @enddate datetime

set @startdate = '2013-02-11'
set @enddate = '2013-02-13'

;with cte (startdate) as
(
  select @startdate
  union all
  select DATEADD(dd, 1, startdate)
  from cte
  where DATEADD(dd, 1, startdate) <= @enddate
)
select *
into #tempDates
from cte;    

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(startdate as date)) 
                    from #tempDates
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT emp_id,' + @cols + ' from 
             (
                select Emp_ID pivId,
                  [Emp_ID], 
                  cast([ontime] as date) ontime
                from test
            ) x
            pivot 
            (
                count(pivId)
                for ontime in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle with Demo。这将返回结果:

| EMP_ID | 2013-02-11 | 2013-02-12 | 2013-02-13 |
-------------------------------------------------
|      1 |          2 |          0 |          1 |
|      2 |          1 |          0 |          1 |
|      3 |          0 |          0 |          1 |

编辑#1,如果您想包括所有员工,那么您将需要在另一个表上使用 JOIN 并且您的代码将与此类似:

declare @startdate datetime
declare @enddate datetime

set @startdate = '2013-02-11'
set @enddate = '2013-02-13'

;with cte (startdate) as
(
  select @startdate
  union all
  select DATEADD(dd, 1, startdate)
  from cte
  where DATEADD(dd, 1, startdate) <= @enddate
)
select *
into #tempDates
from cte;    

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(startdate as date)) 
                    from #tempDates
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT emp_id, Emp_name,' + @cols + ' from 
             (
                select e.Emp_ID pivId,
                  e.[Emp_ID], 
                  e.Emp_name,
                  cast([ontime] as date) ontime
                from Emp_Table e
                left join test t
                  on e.emp_id = t.emp_id
            ) x
            pivot 
            (
                count(pivId)
                for ontime in (' + @cols + ')
            ) p '

execute(@query)

请参阅带有演示的 SQL Fiddle

于 2013-02-11T13:04:55.440 回答