Reputation: 5911
Using Sql Server 2008. We have a table of jobs done. Normally for any customer, job#1 is followed by job#2 which is followed by job#3.
CustNum, JobDate, TypeJob
100, 4/10/2019, 2
100, 4/11/2019, 1
100, 4/12/2019, 2
100, 4/13/2019, 3
100, 4/13/2019, 3
222, 4/10/2019, 2
222, 4/11/2019, 1
333, 4/11/2019, 2
444, 3/1/2019, 3
444, 4/10/2019, 1
444, 4/11/2019, 2
I'm looking for all customers which have job#2 with date > job#1 (both existing) but job#3 was not entered afterward.
Here's what I did and it works but it seems clumsy.
Select
L.CustNum,
L.JobDate1,
L.JobDate2,
R.JobDate3
From
(
--A<B has JobDate1 followed by JobDate2
Select
First.CustNum as [CustNum],
First.JobDate as JobDate1,
Second.JobDate as JobDate2
From
(
Select [CustNum], Max([JobDate]) as JobDate From tbJobs
Where [TypeJob] = 1
Group by CustNum
) First
Join
(
Select [CustNum], Max([JobDate]) as JobDate From tbJobs
Where [TypeJob] = 2
Group by CustNum
) Second
On First.CustNum = Second.CustNum
Where Second.JobDate > First.JobDate
) L
Left Outer Join
(
--A<B #and# C>A has JobDate1 followed by JobDate2 and JobDate3
Select
First.CustNum as [CustNum],
--First.JobDate as JobDate1,
--Second.JobDate as JobDate2,
Third.JobDate as JobDate3
From
(
Select [CustNum], Max([JobDate]) as JobDate From tbJobs
Where [TypeJob] = 1
Group by CustNum
) First
Join
(
Select [CustNum], Max([JobDate]) as JobDate From tbJobs
Where [TypeJob] = 2
Group by CustNum
) Second
On First.CustNum = Second.CustNum
Join
(
Select [CustNum], Max([JobDate]) as JobDate From tbJobs
Where [TypeJob] = 3
Group by CustNum
) Third
On Second.CustNum = Third.CustNum
Where Third.JobDate > First.JobDate
And Second.JobDate > First.JobDate
) R
On First.CustNum = Third.CustNum
Where JobDate3 is null
Order by CustNum
What I really would like to do is something like this:
Select ... From
(Select ...) First
Join
(Select ...) Second
Left Outer Join
(Select ...) Third
On ...
Where Second.JobDate > First.JobDate
And (Third.JobDate > First.JobDate) is null
How would I (is it possible) formulate a Where statement so it ignores any Third.JobDate <= First.JobDate and only finds rows where Third.JobDate (greater than First.JobDate) is null?
Using Sql Server 2008.
Upvotes: 1
Views: 89
Reputation: 1
Use common table expressions:
;WITH First AS (
SELECT CustNum, MAX(JobDate) JobDate1
FROM tbJobs
WHERE TypeJob = 1
GROUP BY CustNum
), Second AS (
SELECT CustNum, MAX(JobDate) JobDate2
FROM tbJobs
WHERE TypeJob = 2
GROUP BY CustNum
), Third AS (
SELECT CustNum, MAX(JobDate) JobDate3
FROM tbJobs
WHERE TypeJob = 3
GROUP BY CustNum
)
SELECT f.CustNum, JobDate1, JobDate2, JobDate3
FROM First f
INNER JOIN Second s ON f.CustNum = s.CustNum AND f.JobDate1 < s.JobDate2
LEFT JOIN Third t ON s.CustNum = t.CustNum AND s.JobDate2 < t.JobDate3
WHERE JobDate3 IS NULL
Upvotes: 0
Reputation: 521178
A simple aggregation query should work here:
WITH cte AS (
SELECT
CustNum,
MAX(CASE WHEN TypeJob = 1 THEN JobDate END) AS date1,
MAX(CASE WHEN TypeJob = 2 THEN JobDate END) AS date2,
MAX(CASE WHEN TypeJob = 3 THEN JobDate END) AS date3
FROM tbJobs
GROUP BY CustNum
)
SELECT CustNum
FROM cte
WHERE
COALESCE(date2, date1) > COALESCE(date1, date2) AND
(date3 < date2 OR date3 IS NULL);
The use of COALESCE
in the HAVING
clause ensures that a customer only passes if he has both the first and second dates present.
Upvotes: 1