2016-04-28 4 views
2

私は、次の問題のSQLソリューションを探しています。 14日以上病気になっている従業員のリストが必要です。期間のステータスを取得するSQL

私は、次のとSQLテーブルをしました:

First_name, Last_Name, INDIRECT_ID, SHIFT_DATE 
John, Doe, Sick, 2016-01-01 
John, Doe, Sick, 2016-01-02 
John, Doe, working, 2016-01-03 
John, Doe, Sick, 2016-01-04 
John, Doe, Sick, 2016-01-05 
etc. 

私は2週間で、彼らは10倍(2倍5営業日)のための病気の場合は見てこれを行うには思いました。しかし、もっと簡単な解決法があるかもしれません。しかし、今私はまた、重複する回答を得ています。

select FIRST_NAME, LAST_NAME 
from (select t.* 
      ,(select count(*) 
       from LABOR_TICKET t2 
       where t2.EMPLOYEE_ID = t.EMPLOYEE_ID and 
        t2.INDIRECT_ID = t.INDIRECT_ID and 
        t2.SHIFT_DATE >= t.SHIFT_DATE and 
        t2.SHIFT_DATE < DATEADD(day, 14, t.SHIFT_DATE)) NumWithin14Days 
     from LABOR_TICKET t 
     where SHIFT_DATE between '2016-01-01' and '2016-04-01' 
    ) LABOR_TICKET 
    INNER JOIN 
         EMPLOYEE ON LABOR_TICKET.EMPLOYEE_ID = EMPLOYEE.ID 

where NumWithin14Days >= 10 AND INDIRECT_ID = 'SICK' 

答えて

0

はまず日付からと日付の間に全14日間の間隔を作成し、これを試してみてください。 次に、すべての従業員の「Sick」のカウントが各インターバルで14であることを確認します。

DECLARE @ST_DATE DATE='2016-01-01' 
     ,@ED_DATE DATE='2016-04-01' 
;WITH CTE_DATE AS (

    SELECT @ST_DATE AS ST_DATE,DATEADD(DAY,13,@ST_DATE) AS ED_DATE 
    UNION ALL 
    SELECT DATEADD(DAY,1,ED_DATE),DATEADD(DAY,14,ED_DATE) 
    FROM CTE_DATE 
    WHERE DATEADD(DAY,14,ED_DATE) <= @ED_DATE 
) 
SELECT FIRST_NAME, LAST_NAME 
FROM CTE_DATE 
    INNER JOIN LABOR_TICKET ON SHIFT_DATE BETWEEN ST_DATE AND ED_DATE 
WHERE INDIRECT_ID = 'Sick' 
GROUP BY FIRST_NAME, LAST_NAME 
HAVING COUNT(*) >= 14 
+0

ありがとう! SQL Management Studioではうまく動作しますが、このコードをMicrosoft SQL Server Report Builderに実装すると、ユーザーは開始日と終了日を選択できます。私はこのエラーがあります: "再帰的な" CTE_DATE "の列" St_DATE "のアンカーと再帰部分の型が一致しません – Scaver

+1

解決策が見つかりました – Scaver

0

擬似コードのすべての従業員のためにあなたに

がアイデアを与えるためにあなたが

create table dates 
(
datetime date 
) 

insert into dates 
select '2016-01-01' 
union all 
select '2016-01-02' 

以下のようなカレンダーのテーブルを持っている場合今、あなたは

select 
mt.firstname,dt.date,count(indirect_id) 
from 
datestable dt 
left join 
maintable mt 
on mt.date=dt.date 
and mt.indirect_id='sick' 
group by mt.firstname,dt.date 
having count(indirect_id)>=14 
order by dt.date 
のようなあなたのメインテーブルでこれに参加左することができます
0

サンプルデータを追加する必要があります。

これを試してください(他のサンプルデータでもうまくいくはずです)。データをフィルタリングするためのものはほとんどありません。

declare @t table(First_name varchar(50), Last_Name varchar(50), INDIRECT_ID varchar(50), SHIFT_DATE date) 
insert into @t values 
('John', 'Doe', 'Sick', '2016-01-01') 
,('John', 'Doe', 'Sick', '2016-01-02') 
,('John','Doe','working','2016-01-03') 
,('John', 'Doe', 'Sick', '2016-01-04') 
,('John', 'Doe', 'Sick', '2016-01-05') 

declare @name varchar(50)='John' 
declare @month int=1 
;With CTE as 
(
    select top 1 First_name,Last_Name,SHIFT_DATE,1 rn from @T where [email protected] 
    and INDIRECT_ID='Sick' order by SHIFT_DATE 
    union all 
    select t.First_name,t.Last_Name,t.SHIFT_DATE, rn+1 from @T t 
    inner join cte c on t.First_name=c.First_name 
where INDIRECT_ID='Sick' 
    and t.SHIFT_DATE=DATEADD(day,1,c.SHIFT_DATE) 
    and t.SHIFT_DATE<='2016-01-31' 
) 

select * from CTE where rn>=14 
0
declare @t table(First_name varchar(50), Last_Name varchar(50), INDIRECT_ID varchar(50), SHIFT_DATE date) 
insert into @t values 
('John', 'Doe', 'Sick', '2016-01-01') 
,('John', 'Doe', 'Sick', '2016-01-02') 
,('John','Doe','working','2016-01-03') 
,('John', 'Doe', 'Sick', '2016-04-04') 
,('John', 'Doe', 'Sick', '2016-05-05') 

select s.* 
     ,u.* 
     ,Sickdays = 
     case 
     when s.indirect_id = 'Sick' and u.indirect_id = 'Sick' then datediff(dd,u.shift_date,s.shift_date) 
     else 0 
     end 
from 
(
select t.*, 
     row_number() over(partition by last_name,first_name order by shift_date desc) rn 
from @t t 
) s 
join  
(select t.*, 
     row_number() over(partition by last_name,first_name order by shift_date desc) rn 
from @t t 
) u on s.last_name = u.last_name and s.first_name = u.first_name and s.rn = u.rn - 1 
where 
     case 
     when s.indirect_id = 'Sick' and u.indirect_id = 'Sick' then datediff(dd,u.shift_date,s.shift_date) 
     else 0 
     end > 13 
+0

日付は英国のyyyymmddにローカライズされています。言うまでもなく、現実世界に参加する従業員IDを持っていれば、それほど簡単ではない作業日に病気を報告しなければならないことは確かです。 –