0

plz 私のテーブル テストを解決します。

ID int
Emp_ID int
日時

select * from test

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

私の要件これ

ユーザー 2 つの日付を入力し、1 日あたりの表示をカウントワイズに記録

ただ記録する

日付 1=2013 年 11 月 2 日 日付 2=2013 年 2 月 13 日

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 に答える