【问题标题】:Enter Two Date and Record Show Per Day Count Wise输入两个日期和记录显示每天计数明智
【发布时间】:2013-02-11 13:00:33
【问题描述】:

请解决我的表格测试

标识整数 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=2013 年 11 月 2 日 日期 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

谢谢


tHx

但是这个 tbl_emp

Emp_ID 整数 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 未插入测试表

【问题讨论】:

  • PIVOT结合动态sql。

标签: sql sql-server sql-server-2008 pivot


【解决方案1】:

这种类型的数据转换称为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 with Demo

【讨论】:

  • tHx 但是这个 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 未插入测试表中
  • @AnilDiggiwal 你没有在测试数据中包含 Emp_ID 4
  • 是的,测试数据中不包括 Emp_ID 4 但这个 tbl_emp (Emp_ID int, Emp_name varchar)
  • @AnilDiggiwal 您可以使用正确的数据编辑您的原始帖子吗?或者用正确的数据编辑这个 sql fiddle -- sqlfiddle.com/#!3/84ad0/4
  • @AnilDiggiwal 查看我的编辑,您将需要在EMP_table 和另一个表之间使用JOIN 来获取所有员工的列表。这是一个工作演示 --sqlfiddle.com/#!3/7e561/5
猜你喜欢
  • 1970-01-01
  • 2020-08-03
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-28
  • 2021-07-08
相关资源
最近更新 更多