2012-09-06 2 views
0

저는 일하는 회사의 데스크톱 지원 팀에 대한 보고서를 작성하고 있습니다. 이 보고서는 ASP.NET 응용 프로그램에서 전달 된 지정된 시간 프레임 내에 새로운 시작 프로그램 집합을 생성해야합니다. 현재 Worker 테이블과 Contract 테이블간에 일대일 관계가 있습니다. 우리는 많은 계약직을 고용하고 때로는 여러 달 후에 돌아 오지만 새로운 기계가 책상 공간과 함께 구성되어야하므로 새로운 시동기처럼 취급됩니다.DATEDIFF() 내에 포함 된 SELECT MAX()

모든 급여 검토, 직위 변경 및 새로운 시동기마다 새로운 계약이 추가됩니다. 우리는 새로운 시동기를 제외한 모든 것을 걸러 낼 필요가있다. 직업 변경 및 급여 검토를 위해 추가되는 최신 계약은 이전 계약의 종료일 이후 자연히 항상 하루입니다. 내가 사물의 웅장한 계획에 아직도 더 새롭기 때문에 나는 내 목표를 성취하기 위해 노력하고있는 일련의 기능들로 고심하고있다. 현재 활성 계약 이전 계약 일일 다른 경우

WHERE  
(dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF) AND DATEDIFF(day, SELECT MAX(StartDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID, SELECT MAX(EndDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID)> 1 

나는 기본적으로 리뷰에 관계없이 떠나 돌아 오는, 직원이 하나 이상의 계약을 맺고 인스턴스에서 찾거나 지불 할 수 있기를 바랍니다. 이것은 내 생각에 모든 새로운 스타터 만 나에게 제공해야한다.

문제는 아직도 때 HAVING 절을 적용하는 경우가 아닌 선택에 집계 함수를 사용하는 방법 주위에 내 머리를 얻으려고 노력하고 있어요입니다.

내 도움이 부족하여이 쿼리/로직이 실패하는 이유를 이해하는 데 도움이 될만한 도움을 주시면 감사하겠습니다.

감사

좋아, 난 아직이 솔루션에서 멀리 강타하고이 구문이 올바르지 않습니다

편집 할 수 있습니다. 여기에 모호성을 없애기 위해 업데이트가 포함 된 쿼리가 있습니다.

Declare @StartDateF varchar(10) 

    Set @StartDateF = '2012-08-03' 

    Declare @EndDateF varchar(10) 
    Set @EndDateF = '2012-09-04' 


    SELECT w1.Worker_ID, w1.Title, w1.FirstName, w1.Surname,w1.Gender, w1.DateofBirth, 
      dbo.[Contract].StartDate, (select w2.surname + ',' + w2.firstname from worker w2 WITH (NOLOCK) where w2.worker_ID = w1.manager)as Manager, dbo.Grade.GradeDescription AS JobTitle, dbo.Grade.Discipline, 
      CASE WHEN dbo.[Contract].ContractType_ID = 1 OR dbo.[Contract].ContractType_ID = 2 OR dbo.[Contract].ContractType_ID = 5 OR dbo.[Contract].ContractType_ID = 6 
      THEN 'Staff' ELSE 'Contractor' END AS ContractType 
    FROM dbo.Worker w1 WITH (NOLOCK) inner join 
     dbo.[Contract] WITH (NOLOCK) ON dbo.[Contract].Worker_ID = w1.Worker_ID inner join 
     dbo.Grade WITH (NOLOCK) ON dbo.Grade.Grade_ID = dbo.[Contract].Grade_ID 
    WHERE 

    (dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF AND EndDate IS NULL) 

    group by 
    w1.Worker_ID, w1.Title, w1.FirstName, w1.Surname,w1.Gender, w1.DateofBirth, 
      dbo.[Contract].StartDate, manager, dbo.Grade.Discipline,dbo.Grade.GradeDescription, dbo.[Contract].ContractType_ID 

    Having DATEDIFF(day, SELECT MAX(StartDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID, SELECT MAX(EndDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID) 

나는에 의해 그룹과 가진 절을 추가했지만 지금은 다음과 같은 오류

에게 메시지 156, 수준 15, 상태 1, 줄 24 'SELECT'키워드 근처의 구문이 잘못을 얻고있다. 메시지 102, 수준 15, 상태 1, 줄 24 ','근처에 구문이 잘못되었습니다. 메시지 102, 수준 15, 상태 1, 줄 24 ')'근처에 구문이 잘못되었습니다.

이 모든 것은 having 절에있는 함수와 관련이 있습니다. 그러나 나는이 쿼리에 무엇이 잘못되었는지를 이해할 수 없으며 이것은 주로 질문입니다. 올바른 솔루션을 구현할 수 있도록 SQL 함수를 충분히 이해해야합니다.

I는 I이 함수 내의 함수를 사용하는 것은 MS 문서에 따라 허용되는 것을 알 수있다 여기 http://msdn.microsoft.com/en-us/library/ms189794.aspx

DATEDIFF() 함수를 따랐다.

편집

HAVING 절을 언급하는 것은 나에게 내가 기대하는 결과 집합을 제공합니다.그것은 계약의 변경 (임금 인상)을 가진 사람을 보여주고 있지만 아무도보고되지 않아야하는 정보이며, 이들은 지금은 몇 가지 개선을 만든 및 극복

편집을 필터링 필요로하는 유일한 기록이다 지금은 오류 메시지가 있지만 여전히 임금 상승이 발생한 사람들이 있습니다. 여기에 하나 이상의 계약 근로자를 얻으려면

group by 
w1.Worker_ID, w1.Title, w1.FirstName, w1.Surname,w1.Gender, w1.DateofBirth, 
     dbo.[Contract].StartDate, manager, dbo.Grade.Discipline,dbo.Grade.GradeDescription, dbo.[Contract].ContractType_ID, w1.Worker_ID 
Having 

(((dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF) 
AND COUNT(dbo.[Contract].Worker_ID) = 1) 

OR 

((dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF) 
AND DATEDIFF(day, (SELECT MAX(EndDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID), (SELECT MAX(StartDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID))>1)) 

답변

0
WHERE ((dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF)AND dbo.[Contract].Worker_ID 
     IN (select worker_id from dbo.[Contract] 
     group by worker_id 
     having count(worker_id) = 1)) 

    OR 

    ((dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF) 
    AND DATEDIFF(day, (SELECT MAX(EndDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID), (SELECT MAX(StartDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID))>1 
    AND dbo.[Contract].Worker_ID = w1.Worker_ID) 

지금 나를 위해 작동 :)

2

에 의해 그룹에서 수정 된 쿼리는 다음을 사용 : 그것은하지만, 소리

select c.workerID 
from Contract c 
group by c.workerID 
having count(distinct contractID) > 1 

, 당신은 단지를 제외한 모든 계산하려는처럼 새로운 시작 것들. 당신은 같은이 작업을 수행 할 수 있습니다 : 당신이 테이블 모양을의 세부 사항을 제공하지 않았기 때문에, 입력 데이터의 모양, 그 결과는 당신이 무엇을 달성하고자하는 샘플이 최고의 관한

select w.workerID 
from Contract c 
where c.ContractType = 'New' 
group by w.workerID 
having count(distinct contractID) > 1 

할 수 있습니다.

+0

덕분에, 그래 당신이 바로 충분한 세부 사항이 없었다 있습니다. 내 최악의 시나리오는 두 번째 스 니펫에서 설명한 내용을 수행하는 것입니다. 현재 우리 계약 형식 테이블은 종업원이 풀 타임, 파트 타임, 인턴, 계약자 등인지 여부를 결정하며 새로운 시동 계약인지 또는 계약시 계약인지 여부를 나타내는 항목이 없습니다. – dotnetnewb

+0

스키마를 변경하는 것이이 새로운 필드를 검사로 사용하는 나의 해결책이었습니다. 그러나 이것이 내가 피하려고하는 것입니다. 주된 이유가 없기 때문에 SQL의 일부로 해결할 수있는 것이라면 나는 그 모든 것을 다룰 수 있습니다. 나는 모든 계약자가 하나 이상의 계약을 맺는 것을 좋아합니다. 계약서의 시작일과 종료일이 최신 계약 인 경우 이전 계약서의 종료일과 하루 달라질 수 있습니다. DATEDIFF 함수를 사용하여 계약 MAX() 시작 날짜를 평가하여 이전 MAX() 및 종료 MAX() 종료 날짜를 얻으려고합니다. – dotnetnewb