Sql-server – Return Bit Value based on previous records by Category

sql serversql server 2014

How would I return TRUE or FALSE if four of the last six records failed for a given MAKEID? So there has to be 4 failures (or FALSE records) in the last six

MAKEID       FAILURES    CREATEDATE
101          TRUE        12/1/2015
101          FALSE       12/5/2015
101          TRUE        12/6/2015
101          FALSE       12/8/2015
101          TRUE        12/10/2015
101          FALSE       12/15/2015
101          FALSE       1/1/2016
101          FALSE       1/2/2016
102          TRUE        12/2/2015
102          TRUE        12/4/2015
102          FALSE       12/5/2015
102          TRUE        12/6/2015
102          FALSE       12/7/2015
102          TRUE        1/1/2016

Query would return the following:

MAKEID    FOUROFLASTSIXFAILED
101       TRUE
102       FALSE

Requirement is there needs to be 4 or more failures in last six records. So if there were 4, 5, or 6 failures in the last six records FOUROFLASTSIXFAILED would return TRUE. If there were only 1, 2, 3 records for a given MAKEID that would return FALSE because there at least needs to be 4 failures in previous six records.

Best Answer

Here is one approach (but please, stop changing your requirements):

DECLARE @x TABLE(MAKEID INT, FAILURES varchar(5), CREATEDATE date);

INSERT @x VALUES
(101,'TRUE ','20151201'),    (101,'FALSE','20151205'),    (101,'TRUE ','20151206'),
(101,'FALSE','20151208'),    (101,'TRUE ','20151210'),    (101,'FALSE','20151215'),
(101,'FALSE','20160101'),    (101,'FALSE','20160102'),    (102,'TRUE ','20151202'),
(102,'TRUE ','20151204'),    (102,'FALSE','20151205'),    (102,'TRUE ','20151206'),
(102,'FALSE','20151207'),    (102,'TRUE ','20160101');

;WITH x AS
(
  SELECT MAKEID, FAILURES,
    -- allow us to identify the last 6 rows:
    rn = ROW_NUMBER() OVER (PARTITION BY MAKEID ORDER BY CREATEDATE DESC)
  FROM @x
)
SELECT MAKEID, FOUROFLASTSIXFAILED = CASE 
  -- make sure there have been at least 6 tests - though this may change:
    WHEN COUNT(*) >= 6 
  -- make sure *at least* 4 of those have failed *within the last 6*
  -- though this may change (again), too:
    AND COUNT(CASE WHEN rn <= 6 AND FAILURES = 'TRUE' THEN 1 END) >= 4 
  THEN 'TRUE' ELSE 'FALSE' END 
FROM x 
GROUP BY MAKEID
ORDER BY MAKEID;

Results (I think these are right, as opposed to the desired output stated in your question, which seem to conflict with your stated requirements):

MAKEID    FOUROFLASTSIXFAILED
------    -------------------
101       FALSE
102       TRUE

It would seem to me that MAKEID = 102 is the only one that has failed exactly four times out of its last six entries, unless the FAILURES column in the original table really represents NOT_FAILURES.